在多线程环境下,通过 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 的简单案例的更多相关文章

  1. [Java Concurrent] 多线程合作 wait / notifyAll 的简单案例

    本案例描述的是,给一辆汽车打蜡.抛光的场景. Car 是一辆被打蜡抛光的汽车,扮演共享资源的角色. WaxOnCommand 负责给汽车打蜡,打蜡时需要独占整部车,一次打一部分蜡,等待抛光,然后再打一 ...

  2. Java:多线程,java.util.concurrent.atomic包之AtomicInteger/AtomicLong用法

    1. 背景 java.util.concurrent.atomic这个包是非常实用,解决了我们以前自己写一个同步方法来实现类似于自增长字段的问题. 在Java语言中,增量操作符(++)不是原子的,也就 ...

  3. java 并发多线程显式锁概念简介 什么是显式锁 多线程下篇(一)

    目前对于同步,仅仅介绍了一个关键字synchronized,可以用于保证线程同步的原子性.可见性.有序性 对于synchronized关键字,对于静态方法默认是以该类的class对象作为锁,对于实例方 ...

  4. JAVA之多线程的创建

    转载请注明源出处:http://www.cnblogs.com/lighten/p/5967853.html 1.概念 老调重弹,学习线程的时候总会牵扯到进程的概念,会对二者做一个区分.网上有较多的解 ...

  5. Java作业-多线程

    未完成,占位以后补 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 书面作业 本次PTA作业题集多线程 源代码阅读:多线程程序BounceThread 1.1 Ball ...

  6. 8.并发编程--多线程通信-wait-notify-模拟Queue

    并发编程--多线程通信-wait-notify-模拟Queue 1. BlockingQueue 顾名思义,首先是一个队列,其次支持阻塞的机制:阻塞放入和获取队列中的数据. 如何实现这样一个队列: 要 ...

  7. 【Java】多线程入门

    Java多线程学习(入门) 前言 目前对于线程的了解仅仅停留在学习python的threading库,很多线程的概念没有真正弄清楚,所以选择来系统性的学习多线程.那么这次选择的是Java的多线程学习, ...

  8. Java的多线程机制系列:(一)总述及基础概念

    前言 这一系列多线程的文章,一方面是个人对Java现有的多线程机制的学习和记录,另一方面是希望能给不熟悉Java多线程机制.或有一定基础但理解还不够深的读者一个比较全面的介绍,旨在使读者对Java的多 ...

  9. Java的多线程机制系列:(三)synchronized的同步原理

    synchronized关键字是JDK5之实现锁(包括互斥性和可见性)的唯一途径(volatile关键字能保证可见性,但不能保证互斥性,详细参见后文关于vloatile的详述章节),其在字节码上编译为 ...

随机推荐

  1. Unix文件操作

    一.概述 Unix文件操作常用函数包括open.close.creat.lseek.dup.dup2.fcntl等, 其中open.creat. fcntl函数需要包含头文件<fcntl.h&g ...

  2. wp-content-index文章目录插件使用效果调整

    安装好wp-content-index后进行如下设置: 其中标红处必须标红,用于检索锚点.在文章页面添加如下js代码: $(function() { var wpindex = $("#co ...

  3. Tips--怎么使用谷歌搜索

    修改hosts即可: hosts在哪? windows下:C:\Windows\System32\drivers\etc 管理员身份打开,并将下载好的hosts文件内容,添加到原有的hosts文件末尾 ...

  4. 构建可比较的对象(IComparable)

    IComparable接口 System.IComparable接口指定了一种允许一个对象可基于某些特定键值进行排序的行为. namespace System { [ComVisible(true)] ...

  5. HDU5311

    题意:给一个指定的字符串a,要求分成三段,然后再给定另外一个字符串b,要求a中的三段能否在b中找到. 思路:枚举+模拟,首先枚举给定的字符串a,因为分成三段,所以一共有(1+9)*9/2种情况,对于分 ...

  6. Android中Action

    1 Intent.ACTION_MAIN String: android.intent.action.MAIN 标识Activity为一个程序的开始.比较常用. <activity androi ...

  7. spring-data-mongodb查询结果返回指定字段

        方法1 DBObject dbObject = new BasicDBObject(); dbObject.put("status", 1); DBObject field ...

  8. 02-测试、文件读写、xml解析

    测试 黑盒测试 测试逻辑业务 白盒测试 测试逻辑方法 根据测试粒度 方法测试:function test 单元测试:unit test 集成测试:integration test 系统测试:syste ...

  9. ONVIF Event消息解析(How to work with gSoap)

    Prepare Requirements ONVIF Event gSoap reference ONVIF Specification 问题描述 Event是ONVIF核心规范中一块, 文档解释了如 ...

  10. 简洁的MysqlHelper

    把MySqlXXX的类更改为SqlXXX就可以成为sqlHelper. 另外C#也提供了MysqlHelper和sqlHelper,用起来也挺方便的. public class MySqlHelper ...