在这个高并发时代最重要的设计模式无疑是生产者、消费者模式,比如著名的消息队列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. 【二级java】操作题知识点积累
  2. 1.15 实例内部类
  3. Lucene学习之——停用词
  4. DNS子域授权及view(三)
  5. Linux配置最基础的命令
  6. [机器学习-实践]支持向量机(SVM)从例子代码中学习
  7. bzoj2245 [SDOI2011]工作安排 费用流
  8. 4chan 爬虫_类似4chan网站
  9. 《和平精英》玩跨界,特斯拉主题店超级充电站现身海岛
  10. 买SUV要不要选四驱,有哪些区别?
  11. Ubuntu首页挂预告,预计今晚12点推出平板Ubuntu系统
  12. 【LeetCode】【数组】题号:*453,数组元素相等的最小操作次数
  13. hibernate5.x下载地址
  14. 在matlab中饼图种类,Excel2016中饼图的常见类型及绘制方法
  15. python sphinx_Python Sphinx 生成简洁大方的文档
  16. 阿里云云服务器 ECS基础知识
  17. 安卓手机屏幕失灵后通讯录导出
  18. Win7 + VirtualBox 安装 MacOS X 10.9 Mavericks 操作步骤
  19. 网易或入股MSN中国 门户再现竞争新局
  20. 520表白神器-教你用微信每天给TA说晚安

热门文章

  1. linux下怎么卸载mysql数据库_linux 怎么完全卸载mysql数据库
  2. 《惢客创业日记》2020.03.16-31(周一) 国家有难,匹夫有责(三)
  3. 一、「下载JDK」「配置JDK」「下载JDK文档」
  4. MySQL图书管理系统设计
  5. kafka权威指南学习笔记
  6. Qt Design Studio组态软件简介及源码下载
  7. linux 小巧的浏览器,崇尚简约 六款小体积浏览器推荐
  8. 工作学习总结--ng2-pdf-viewer的运用
  9. 联想r720游戏模式不见了
  10. 转载 游戏设计艺术中100个透镜