并发编程模式(future,Master-Worker,生产者消费者模式)

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
云原生网关 MSE Higress,422元/月
可观测可视化 Grafana 版,10个用户账号 1个月
简介: 在网上购物时,提交订单后,在收货的这段时间里无需一直在家里等候,可以先干别的事情。类推到程序设计中时,当提交请求时,期望得到答复时,如果这个答复可能很慢。传统的是一直等待到这个答复收到时再去做别的事情,但如果利用Future设计模式就无需等待答复的到来,在等待答复的过程中可以干其他事情。

一、future模式

在网上购物时,提交订单后,在收货的这段时间里无需一直在家里等候,可以先干别的事情。类推到程序设计中时,当提交请求时,期望得到答复时,如果这个答复可能很慢。传统的是一直等待到这个答复收到时再去做别的事情,但如果利用Future设计模式就无需等待答复的到来,在等待答复的过程中可以干其他事情。

future模式核心思想就是异步调用,去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑。

下面是时序图,左边是传统的单线程执行,右边使用了future模式。

我们通过synchronized结合wait()和notify()、并发包下的锁都可以实现future模式,不过JDK已经为我们提供了future模式的实现,位于java.util.concurrent并发包下。

二、Master-Worker模式

Master-Worker 模式是常用的并行计算模式。它的核心思想是系统由两类进程协作工作:Master 进程和 Worker 进程。Master 负责接收和分配任务,Worker 负责处理子任务。当各个 Worker 子进程处理完成后,会将结果返回给 Master , 由 Master 进行归纳和总结。其好处是能将一个大任务分解成若干个小任务,并行执行,从而提高系统的吞吐量。

在Master端往往会有如下的内容:

1、一个盛放任务的容器,一般使用队列来保证先添加的任务先执行,因为在下面参考文章的例子中,任务在main方法中被直接一口气全部提交过来,所以worker不需要在没有任务可以取的时候而阻塞等待新任务,也就是不牵涉到阻塞,所以在这里推荐使用非阻塞的线程安全队列ConcurrentLinkedQueue性能更好,参考文章中也是使用了这种队列。

2、一个盛放worker的线程集合,worker就是用来执行任务的,所以就是个子线程,所以可以使用HashMap<String, Thread>来盛放,key是每个worker线程的标识。

3、一个盛放任务结果的集合,和盛放worker的线程集合不同,worker的线程集合就是在初始化Master时需要指定有多少个worker的,所以是一并初始化好的,没有并发也就没有线程安全问题,而任务结果的集合会被多个worker访问,需要线程安全的容器才行,推荐ConcurrentHashMap。

每个worker端往往会有如下的内容:

1、Master里盛放任务的容器的引用,因为需要获取任务。

2、Master里盛放任务结果集合,因为需要把处理完的任务结果放进去。

Master-Worker模式的实现可参考文章:http://blog.csdn.net/lv_fq/article/details/70853315

三、生产者-消费者模式

生产者-消费者模式是一个经典的多线程设计模式。它为多线程间的协作提供了良好的解决方案。 在生产者-消费者模式中,通常有两类线程,即若干个生产者线程和若干个消费者线程。生产者线程负责提交用户请求,消费者线程则负责具体处理生产者提交的任务。生产者和消费者之间则通过共享内存缓冲区进行通信。

生产者-消费者模式可以通过线程间通信的方式实现,例如通过synchronized结合wait()和notify()、并发包下的锁都可以。但最好的方式是使用阻塞队列来实现,阻塞队列又是线程安全的这样不仅高效而且实现非常简单,将阻塞队列作为存放数据的内存缓冲区,通过调用阻塞队列的阻塞方法put()和take(),开发者不需要写困惑的wait-nofity代码去实现通信。

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

相关文章
|
设计模式 并行计算 安全
并发编程模式(future,Master-Worker,生产者消费者模式)
在网上购物时,提交订单后,在收货的这段时间里无需一直在家里等候,可以先干别的事情。类推到程序设计中时,当提交请求时,期望得到答复时,如果这个答复可能很慢。传统的是一直等待到这个答复收到时再去做别的事情,但如果利用Future设计模式就无需等待答复的到来,在等待答复的过程中可以干其他事情。 future模式核心思想就是异步调用,去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑。
|
设计模式 Java API
【JUC基础】15. Future模式
Future 模式是多线程开发中非常常见的一种设计模式,它的核心思想是异步调用。当我们需要调用一个函数方法时,如果这个函数执行得很慢,那么我们就要进行等待。但有时候,我们可能并不急着要结果。因此,我们可以让被调者立即返回,让它在后台慢慢处理这个请求。对于调用者来说,则可以先处理一些其他任务,在真正需要数据的场合再去尝试获得需要的数据。
145 0
【JUC基础】15. Future模式
|
设计模式 Java 测试技术
异步模式之工作线程
异步模式之工作线程
|
设计模式 并行计算 容器
多线程设计模式 : Master-Worker模式
多线程设计模式 : Master-Worker模式
268 0
|
Java C++
高并发编程-Daemon Thread的创建以及使用场景分析
高并发编程-Daemon Thread的创建以及使用场景分析
107 0
|
安全 Java API
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(一)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(一)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(二)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(二)
|
Linux 调度
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(三)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(三)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(四)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)
《JUC并发编程 - 高级篇》03 - 共享对象之管程 下篇(Monitor | wait&notify | Park&Unpark | 线程状态转换 | 活跃性 | ReentrantLock)(四)
|
Java
【多线程:Monitor 概念】
【多线程:Monitor 概念】
146 0