[Java Concurrent] 多线程合作 producer-consumers / queue 的简单案例
在多线程环境下,通过 BlockingQueue,实现生产者-消费者场景。
Toast 被生产和消费的对象。
ToastQueue 继承了 LinkedblockingQueue ,用于中间存储 Toast 。
Producer 生产 Toast ,并将生产出来的 Toast 放进队列 initialToastQ 中。
Processor 加工 Toast,从 initialToastQ 中获得生产出来的 Toast,将其加工并放进队列 finishedToast 中。
Consumer 消费 Toast,从 finishedToastQ 中获得加工完成的 Toast。
ThreadHelper 工具类,用于输出线程相关信息。
ProducerConsumerDemo 演示这个场景

代码实现:
Toast 实现
public class Toast {
private int id;
public Toast(int id){
this.id = id;
}
public String toString(){
return " toast#" + id;
}
}
ToastQueue 实现
import java.util.concurrent.LinkedBlockingQueue;
public class ToastQueue extends LinkedBlockingQueue<Toast> {
private static final long serialVersionUID = 1L;
}
Producer 循环生产 Toast
import java.util.concurrent.TimeUnit;
public class Producer implements Runnable {
private ToastQueue toastQueue;
private int count;
public Producer(ToastQueue toastQueue){
this.toastQueue = toastQueue;
this.count = 0;
}
@Override
public void run() {
try {
while (true){
TimeUnit.MILLISECONDS.sleep(100);
Toast toast = new Toast(count);
count++;
toastQueue.put(toast);
ThreadHelper.print(" produced " + toast);
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Processor 从 intialToastQ 获得 Toast ,对其加工,并放进 finishedToastQ 中。
import java.util.concurrent.TimeUnit;
public class Processor implements Runnable {
private ToastQueue initialToastQ;
private ToastQueue finishedToastQ;
public Processor(ToastQueue initialToastQ, ToastQueue finishedToastQ){
this.initialToastQ = initialToastQ;
this.finishedToastQ = finishedToastQ;
}
@Override
public void run() {
try {
while (true){
Toast toast = initialToastQ.take();
ThreadHelper.print(" processing " + toast);
TimeUnit.MILLISECONDS.sleep(180);
finishedToastQ.put(toast);
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Consumer 消耗 Toast
public class Consumer implements Runnable {
private ToastQueue finishedToastQ;
public Consumer(ToastQueue finishedToastQ){
this.finishedToastQ = finishedToastQ;
}
@Override
public void run() {
try {
while (true){
Toast toast = finishedToastQ.take();
ThreadHelper.print(" consumed " + toast);
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
ThreadHelper 线程帮助类
public class ThreadHelper {
public static void print(String msg){
System.out.println("[" + Thread.currentThread().getName() + " ] " + msg);
}
}
演示烤面包的生产、加工、消费的场景
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; public class ProducerConsumerDemo { public static void main() throws InterruptedException{ ToastQueue initialToastQ = new ToastQueue();
ToastQueue finishedToastQ = new ToastQueue(); ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Producer(initialToastQ));
exec.execute(new Processor(initialToastQ, finishedToastQ));
exec.execute(new Consumer(finishedToastQ)); TimeUnit.SECONDS.sleep(2);
exec.shutdownNow();
}
}
输出结果:
[pool--thread- ] processing toast#
[pool--thread- ] produced toast#
[pool--thread- ] produced toast#
[pool--thread- ] processing toast#
[pool--thread- ] consumed toast#
[pool--thread- ] produced toast#
[pool--thread- ] produced toast#
[pool--thread- ] processing toast#
[pool--thread- ] consumed toast#
[pool--thread- ] produced toast#
[pool--thread- ] produced toast#
[pool--thread- ] processing toast#
[pool--thread- ] consumed toast#
[pool--thread- ] produced toast#
[pool--thread- ] produced toast#
[pool--thread- ] processing toast#
[pool--thread- ] consumed toast#
[pool--thread- ] produced toast#
[pool--thread- ] processing toast#
[pool--thread- ] consumed toast#
[pool--thread- ] produced toast#
[pool--thread- ] produced toast#
[pool--thread- ] processing toast#
[pool--thread- ] consumed toast#
[pool--thread- ] produced toast#
[pool--thread- ] produced toast#
[pool--thread- ] processing toast#
[pool--thread- ] consumed toast#
[pool--thread- ] produced toast#
[pool--thread- ] produced toast#
[pool--thread- ] processing toast#
[pool--thread- ] consumed toast#
[pool--thread- ] produced toast#
[pool--thread- ] produced toast#
[pool--thread- ] processing toast#
[pool--thread- ] consumed toast#
[pool--thread- ] produced toast#
[pool--thread- ] processing toast#
[pool--thread- ] consumed toast#
[pool--thread- ] produced toast#
java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:)
at concurrencyProducerConsumer.Consumer.run(Consumer.java:)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:)
at java.lang.Thread.run(Thread.java:)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:)
at concurrencyProducerConsumer.Producer.run(Producer.java:)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:)
at java.lang.Thread.run(Thread.java:)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:)
at concurrencyProducerConsumer.Processor.run(Processor.java:)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:)
at java.lang.Thread.run(Thread.java:)
参考资料
Page 868, Produer-consumers and queue, Thinking in Java
[Java Concurrent] 多线程合作 producer-consumers / queue 的简单案例的更多相关文章
- [Java Concurrent] 多线程合作 wait / notifyAll 的简单案例
本案例描述的是,给一辆汽车打蜡.抛光的场景. Car 是一辆被打蜡抛光的汽车,扮演共享资源的角色. WaxOnCommand 负责给汽车打蜡,打蜡时需要独占整部车,一次打一部分蜡,等待抛光,然后再打一 ...
- Java:多线程,java.util.concurrent.atomic包之AtomicInteger/AtomicLong用法
1. 背景 java.util.concurrent.atomic这个包是非常实用,解决了我们以前自己写一个同步方法来实现类似于自增长字段的问题. 在Java语言中,增量操作符(++)不是原子的,也就 ...
- java 并发多线程显式锁概念简介 什么是显式锁 多线程下篇(一)
目前对于同步,仅仅介绍了一个关键字synchronized,可以用于保证线程同步的原子性.可见性.有序性 对于synchronized关键字,对于静态方法默认是以该类的class对象作为锁,对于实例方 ...
- JAVA之多线程的创建
转载请注明源出处:http://www.cnblogs.com/lighten/p/5967853.html 1.概念 老调重弹,学习线程的时候总会牵扯到进程的概念,会对二者做一个区分.网上有较多的解 ...
- Java作业-多线程
未完成,占位以后补 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 书面作业 本次PTA作业题集多线程 源代码阅读:多线程程序BounceThread 1.1 Ball ...
- 8.并发编程--多线程通信-wait-notify-模拟Queue
并发编程--多线程通信-wait-notify-模拟Queue 1. BlockingQueue 顾名思义,首先是一个队列,其次支持阻塞的机制:阻塞放入和获取队列中的数据. 如何实现这样一个队列: 要 ...
- 【Java】多线程入门
Java多线程学习(入门) 前言 目前对于线程的了解仅仅停留在学习python的threading库,很多线程的概念没有真正弄清楚,所以选择来系统性的学习多线程.那么这次选择的是Java的多线程学习, ...
- Java的多线程机制系列:(一)总述及基础概念
前言 这一系列多线程的文章,一方面是个人对Java现有的多线程机制的学习和记录,另一方面是希望能给不熟悉Java多线程机制.或有一定基础但理解还不够深的读者一个比较全面的介绍,旨在使读者对Java的多 ...
- Java的多线程机制系列:(三)synchronized的同步原理
synchronized关键字是JDK5之实现锁(包括互斥性和可见性)的唯一途径(volatile关键字能保证可见性,但不能保证互斥性,详细参见后文关于vloatile的详述章节),其在字节码上编译为 ...
随机推荐
- Apache MINA NioSocketAcceptor类的实现
NioSocketAcceptor 继承AbstractPollingIoAcceptor,实现SocketAcceptor接口 public final class NioSocketAccepto ...
- 9.6noip模拟试题
题目名称 盘子序列 四轮车 点名 提交文件 disk.pas/c/cpp car.pas/c/cpp rollcall.pas/c/cpp 输入文件 disk.in car.in rollcall.i ...
- C#反射—解决类的实例化问题
利用简单工厂模式来改进抽象工厂使用的复杂性(抽象工厂详见 设计模式之—抽象工厂模式) 数据表(User)业务处理接口(IUser) namespace FactoryMethodPatternDB.C ...
- readonly 与 const
readonly MSDN定义:readonly 关键字是可以在字段上使用的修饰符.当字段声明包括 readonly 修饰符时,该声明引入的字段赋值只能作为声明的一部分出现,或者出现在同一类的构造函数 ...
- 使用ul,添加新闻信息列表
在浏览网页时,你会发现网页上有很多信息的列表,如新闻列表.图片列表,如下图所示. 新闻列表 图片列表 这些列表就可以使用ul-li标签来完成.ul-li是没有前后顺序的信息列表. 语法: <ul ...
- iOS开发: 向右滑动手势功能实现
在navigationController中实现向右滑动 返回功能 系统提供的backbarbuttonitem,不用添加任何代码即可实现向右滑动后退功能,但是往往要对按钮修改样式等时,就需要自定义l ...
- Java学习----构造方法的重载
一个类中有多个同名的参数不一样(参数的个数,参数的类型,参数的顺序)的构造方法 public class Student { public Student() { System.out.println ...
- 11_RHEL安装Maya2015
1. 解压 tar -xvf ./Autodesk_Maya_English_2015_Linux_64bit.tgz 2. 运行 ./setup 2.1补充 如果提示缺少 libpng12.so.0 ...
- python+flask+mongodb+whoosh实现自己的搜索引擎(一):目录
python+flask+jieba+mongodb+whoosh实现自己的搜索引擎 一.目录 二.基于python的爬虫 三.网页去燥,URL去重 四.基于mongodb的数据存储 五.基于whoo ...
- Delphi-Delete 过程
过程名称 Delete 所在单元 System 过程原型 procedure Delete ( var Source : string; StartChar : Integer; Count : In ...