Java 多线程设计模式之Producer-Consumer

11 篇文章 0 订阅
2 篇文章 0 订阅
Producer-Consumer 模式通过在数据的生产者和消费者之间引入一个通道(Channel, 暂时可以将其简单地理解为一个队列)对二者进行解耦(Decouping):生产者将其生产的数据放入通道,消费者从相应通道中取出数据进行消费,生产者和消费者各自运行在各自的线程中,从而使双方处理速率互补影响。

7.4.1 通道积压

当消费者的处理能力低于生产者的处理能力时,随着时间的推移,通道中存储的“产品”会越来越多而出现挤压现象。常见的处理方法有两种:
1. 使用有界阻塞队列,使用有界阻塞队列(如ArrayBlokingQueue 和带容量限制的LinkedBlockingQueue)作为Channel 参与者的实现可以实现将消费者的处理压力“反弹”给生产者。具体莱索,当通道的有界阻塞队列逐渐积压到队列满,此时生产者线程会被阻塞直到相应的消费者“消费”了队列的一些”产品“,使得队列非满。
2. 使用带流量控制的无界阻塞队列。使用无界阻塞队列(如不带容量限制的LinkBlockingQueue),借助控制流量实现,即对同一时间内可以有多少个生产者线程往通道中存储”产品“进行限制。

7.4.2 工作窃取方法

如果一个通道实例对应于多个队列实例,那么就可以实现多个消费者线程从通道中取“产品”的时候访问的是各自的队列实例,此时,各个消费者线程修改队列的头指针并不会导致锁竞争。
工作窃取(Work Stealing) 算思想,当一个消费者线程处理完该线程对应的队列中的“产品”时,它可以继续从其他消费者线程对应的队列中取出“产品”进行处理。

JDK 1.5 引入的标准库类 java.util.concurrent.ThreadPoolExecutor 可以看成是Producer-Consummer模式的可服用实现。 ThreadPoolExecutor 内部维护的工作队列和工作者线程相当于Producer-Consumer 模式的Channel 参与者和Consumer 参与者。而ThreadPoolExecutor 的客户端代码则相当于Producer 参与者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值