在这个高并发时代最重要的设计模式无疑是生产者、消费者模式,比如著名的消息队列kafka其实就是一个巨型的生产者消费者模式的实现。生产者消费者问题,也称有限缓冲问题,是一个并发环境编程的经典案例。生产者生成一定量的产品放到库房,并不断重复此过程;与此同时,消费者也在缓冲区消耗这些数据,但由于库房大小有限,所以生产者和消费者之间步调协调,生产者不会在库房满的情况放入端口,消费者也不会在库房空时消耗数据。详见下图:

而从GO语言并发模型来看,利用channel确实能达到共享内存的目的,因为channel的性质和一块带有读写状态且保证数据顺序的共享内存并无二致。但通过前面的介绍读者也许也能发现,消息队列的封装程度明显可以做的更高,因此GO语言之父们才说会要通过通信来共享内存。

为了帮助大家找到区别,我们先以Java为例来看一下没有channel的情况下,生产者消费者如何实现。Java的代码及注释如下:

public class Storage {// 仓库最大存储量private final int MAX_SIZE = 10;// 仓库存储的载体private LinkedList<Object> list = new LinkedList<Object>();// 锁private final Lock lock = new ReentrantLock();// 仓库满的信号量private final Condition full = lock.newCondition();// 仓库空的信号量private final Condition empty = lock.newCondition();public void produce(){// 获得锁lock.lock();while (list.size() + 1 > MAX_SIZE) {System.out.println("【生产者" + Thread.currentThread().getName()+ "】仓库已满");try {full.await();} catch (InterruptedException e) {e.printStackTrace();}}list.add(new Object());System.out.println("【生产者" + Thread.currentThread().getName() + "】生产一个产品,现库存" + list.size());empty.signalAll();lock.unlock();}public void consume(){// 获得锁lock.lock();while (list.size() == 0) {System.out.println("【消费者" + Thread.currentThread().getName()+ "】仓库为空");try {empty.await();} catch (InterruptedException e) {e.printStackTrace();}}list.remove();System.out.println("【消费者" + Thread.currentThread().getName()+ "】消费一个产品,现库存" + list.size());full.signalAll();lock.unlock();}
}

在没有channel的编程语言如JAVA中这种生产者、消费者模式至少要借助一个lock和两个信号量共同完成。其中锁的作用是保证同是时间,仓库中只有一个用户进行数据的修改,而还需要表示仓库满的信号量,一旦达到仓库满的情况则将此信号量置为阻塞状态,从而阻止其它生产者再向仓库运商品了,反之仓库空的信号量也是一样,一旦仓库空了,也要阻其它消费者再前来消费了。

我们刚刚也介绍过了GO语言中的channel其实就是基于lock实现的循环队列,所以不需要再添加lock和信号量就能实现模式了,以下代码中我们通过子goroutine完成了生产者的功能,在主goroutine中实现了消费者的功能,注意channel的读取必须放在不同的goroutine当中,轻而易举的就这完成了生产者消费者模式。下面我们就通过具体实践中来看一下生产者消费者模型的实现。

package mainimport ("fmt"
)func Product(ch chan<- int) { //生产者for i := 0; i < 3; i++ {fmt.Println("Product  produceed", i)ch <- i //由于channel是goroutine安全的,所以此处没有必要必须加锁或者加lock操作.}
}
func Consumer(ch <-chan int) {for i := 0; i < 3; i++ {j := <-ch //由于channel是goroutine安全的,所以此处没有必要必须加锁或者加lock操作.fmt.Println("Consmuer consumed ", j)}
}
func main() {ch := make(chan int)go Product(ch)Consumer(ch)/*运行结果为Product  produceed 0Product  produceed 1Consmuer consumed  0Consmuer consumed  1Product  produceed 2Consmuer consumed  2*/}

可以看到和Java比起来使用GO来实现并发式的生产者消费者模式的确是更为清爽了。

高并发时代下的设计模式-GO和JAVA的对比相关推荐

  1. oracle rac 高并发性能_高并发业务下 JVM 涉及的垃圾回收与性能问题分析与定位...

    最近好多 Java 的朋友问:"高并发业务场景下,JVM涉及的性能问题好难搞呀--".看来是大家的技术经验相对少了些,拿不准该从哪些地方上手,其实,每个技术人要该懂得怎样更好打造自 ...

  2. 读数据库遇到空就进行不下去_如何解决高并发场景下缓存+数据库双写不一致问题?...

    推荐阅读: 一只Tom猫:手撕分布式技术:限流.通讯.缓存,全部一锅端走送给你!​zhuanlan.zhihu.com 一只Tom猫:MySQL复习:20道常见面试题(含答案)+21条MySQL性能调 ...

  3. 华为云:如何解除数据库高并发场景下的达摩克利斯之剑?

    5月10-12日,第九届中国数据库技术大会(DTCC 2018)如约而至.大会邀请了百余位行业专家,就数据库.大数据等热点技术话题进行分享.其中,华为云数据库首席架构师 带来的主题演讲<MySQ ...

  4. 并发经验八年架构师:缓存在高并发场景下该如何问题

    缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象.这就比较依赖缓存的过期和更新策略.一般会在数据发生更改 ...

  5. 【高并发】高并发环境下构建缓存服务需要注意哪些问题?我和阿里P9聊了很久!

    写在前面 周末,跟阿里的一个朋友(去年晋升为P9了)聊了很久,聊的内容几乎全是技术,当然了,两个技术男聊得最多的话题当然就是技术了.从基础到架构,从算法到AI,无所不谈.中间又穿插着不少天马行空的想象 ...

  6. 高并发场景下数据库的常见问题及解决方案

    一.分库分表 (1)为什么要分库分表 随着系统访问量的增加,QPS越来越高,数据库磁盘容量不断增加,一般数据库服务器的QPS在800-1200的时候性能最佳,当超过2000的时候sql就会变得很慢并且 ...

  7. 【高并发】高并发环境下构建缓存服务需要注意哪些问题?我和阿里P9聊了很久!...

    写在前面 周末,跟阿里的一个朋友(去年晋升为P9了)聊了很久,聊的内容几乎全是技术,当然了,两个技术男聊得最多的话题当然就是技术了.从基础到架构,从算法到AI,无所不谈.中间又穿插着不少天马行空的想象 ...

  8. 高并发环境下如何优化Tomcat性能?看完我懂了!

    来自:冰河技术 写在前面 Tomcat作为最常用的Java Web服务器,随着并发量越来越高,Tomcat的性能会急剧下降,那有没有什么方法来优化Tomcat在高并发环境下的性能呢? Tomcat运行 ...

  9. 【高并发】在高并发环境下该如何构建应用级缓存?

    来自:冰河技术 写在前面 随着我们的系统负载越来越高,系统的性能就会有所下降,此时,我们可以很自然地想到使用缓存来解决数据读写性能低下的问题.但是,立志成为资深架构师的你,是否能够在高并发环境下合理并 ...

  10. 高并发场景下缓存的常见问题

    作者介绍: 丁浪,非著名架构师.关注高并发.高可用的架构设计,对系统服务化.分库分表.性能调优等方面有深入研究和丰富实践经验.热衷于技术研究和分享. 声明:版权归丁浪作者本人所有,转载请联系作者本人 ...

最新文章

  1. LIVE 预告 | CVPR 2021 预讲 · 旷视专场,覆盖目标检测、蒸馏、图像降噪、人体姿态估计等...
  2. 10 个 GitHub 上最火的程序员简历项目,2021 金三银四必备!
  3. linux系统修改系统时间
  4. vs.net 2005 中自定义模版项
  5. PP视频如何设置关闭的时候直接退出程序
  6. UI(1)---2018 UI 设计趋势
  7. Altium Designer软件插件之封装神器Altium Library Loader
  8. 白盒测试用例设计方法(语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组合覆盖、路径覆盖、基本路径覆盖)
  9. 将照片转换为网站的Flash
  10. The Apache Tomcat Native library which allows using OpenSSL was not found on the java.library.path
  11. 21 C++ 长度单位转换
  12. 大学英语(第四册)复习(原文及全文翻译)——Unit 10 - Why People Work(人为什么工作)
  13. Elliptic Curve Cryptography: a gentle introduction
  14. 计算机数列类型,斐波那契(Fibonacci)数列的几种计算机解法
  15. 【经验帖】深度学习如何训练出好的模型
  16. TX Text Control文字处理教程(4)标记文本域
  17. python人机交互_人机交互程序 python实现人机对话
  18. Spring 基本配置
  19. 2345内核拒绝服务漏洞(3)- WORD的锅
  20. HTML 如何获取输入框的值

热门文章

  1. 蛋白质聚集的分子动力学模拟
  2. 央妈:银联,想说爱你不容易
  3. Oracle sql优化工具
  4. (软件项目管理)项目会议纪要模板
  5. Tabulator PDF下载中文字体设置
  6. sql 获取当前之后某天的日期
  7. 30 Essential Pieces Of Free (and Open) Software for Windows-windows系统30个开源软件
  8. 压缩壳的实现相关细节(强奸PE)
  9. matlab步长教程,matlab仿真步长
  10. 奥维怎么记录沿线轨迹_奥维地图如何绘制轨迹