1. 吐司BlockingQueue

    考虑下面这个使用BlockingQueue的示例。有一台机器具有三个任务:一个制作吐司,一个给吐司抹黄油,另一个在抹过黄油的吐司上吐果酱。我们可以通过各个处理过程之间的BlockingQueue来运行这个吐司制作程序:

  2. class :

package lime.thinkingInJava._021._005._004;

import com.sun.corba.se.impl.oa.toa.TOA;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit; /**
* @Author : Lime
* @Description :
* @Remark :
*/
class Toast{
public enum Status{DRY,BUTTERED,JAMMED}
private Status status = Status.DRY;
private final int id;
public Toast(int idn){id = idn;}
public void butter(){
status = Status.BUTTERED;
}
public void jam(){
status = Status.JAMMED;
}
public Status getStatus(){
return status;
}
public int getId(){
return id;
}
public String toString(){
return "Toast " + id + " : " + status;
}
}
class ToastQueue extends LinkedBlockingQueue<Toast>{} class Toaster implements Runnable{
private ToastQueue toastQueue;
private int count = 0;
private Random rand = new Random(47);
public Toaster(ToastQueue tq){
toastQueue = tq;
}
public void run(){
try{
while (!Thread.interrupted()){
TimeUnit.MILLISECONDS.sleep(100 + rand.nextInt(100));
//Make toast
Toast t = new Toast(count++);
System.out.println(t);
//Insert into queue
toastQueue.put(t);
}
} catch (InterruptedException e) {
System.out.println("Toaster interrupted");
}
System.out.println("Toaster off");
}
}
//Apply butter to toast
class Butterer implements Runnable{
private ToastQueue dryQueue ,butteredQueue;
public Butterer(ToastQueue dry , ToastQueue buttered){
dryQueue = dry;
butteredQueue = buttered;
}
public void run(){
try{
while (!Thread.interrupted()){
//Blocks until next piece of toast is available;
Toast t = dryQueue.take();
t.butter();
System.out.println(t);
butteredQueue.put(t);
}
} catch (InterruptedException e) {
System.out.println("Butterer interrupted");
}
System.out.println("Butterer off");
}
}
//Apply jam to buttered toast;
class Jammer implements Runnable{
private ToastQueue butteredQueue,finishedQueue;
public Jammer(ToastQueue buttered,ToastQueue finished){
butteredQueue = buttered;
finishedQueue = finished;
}
public void run(){
try{
while (!Thread.interrupted()){
//Blocks until next piece of toast is available;
Toast t = butteredQueue.take();
t.jam();
System.out.println(t);
finishedQueue.put(t);
}
} catch (InterruptedException e) {
System.out.println("Jammer interrupted");
}
System.out.println("Jammer off");
}
}
//Consume the toast;
class Eater implements Runnable{
private ToastQueue finishedQueue;
private int counter = 0;
public Eater(ToastQueue finished){
this.finishedQueue = finished;
}
public void run(){
try{
while (!Thread.interrupted()){
//Blocks until next piece of toast is available;
Toast t = finishedQueue.take();
//Verify that the toast is coming in order;
//and that all pieces are getting jammed;
if(t.getId() != counter++ || t.getStatus() != Toast.Status.JAMMED){
System.out.println(">>>> Error : " + t);
System.exit(1);
}else{
System.out.println("Chomp ! " + t);
}
}
} catch (InterruptedException e) {
System.out.println("Eater interrupted");
}
System.out.println("Eater off");
}
}
public class ToastOMatic {
public static void main(String[] args) throws InterruptedException {
ToastQueue dryQueue = new ToastQueue(),
butteredQueue = new ToastQueue(),
finishedQueue = new ToastQueue();
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Toaster(dryQueue));
exec.execute(new Butterer(dryQueue,butteredQueue));
exec.execute(new Jammer(butteredQueue,finishedQueue));
TimeUnit.SECONDS.sleep(5);
exec.shutdownNow();
}
}

  3. Console :

Toast 0 : DRY
Toast 0 : BUTTERED
Toast 0 : JAMMED
Toast 1 : DRY
Toast 1 : BUTTERED
Toast 1 : JAMMED
Toast 2 : DRY
Toast 2 : BUTTERED
Toast 2 : JAMMED
Toast 3 : DRY
Toast 3 : BUTTERED
Toast 3 : JAMMED
Toast 4 : DRY
Toast 4 : BUTTERED
Toast 4 : JAMMED
Toast 5 : DRY
Toast 5 : BUTTERED
Toast 5 : JAMMED
Toast 6 : DRY
Toast 6 : BUTTERED
Toast 6 : JAMMED
Toast 7 : DRY
Toast 7 : BUTTERED
Toast 7 : JAMMED
Toast 8 : DRY
Toast 8 : BUTTERED
Toast 8 : JAMMED
Toast 9 : DRY
Toast 9 : BUTTERED
Toast 9 : JAMMED
Toast 10 : DRY
Toast 10 : BUTTERED
Toast 10 : JAMMED
Toast 11 : DRY
Toast 11 : BUTTERED
Toast 11 : JAMMED
Toast 12 : DRY
Toast 12 : BUTTERED
Toast 12 : JAMMED
Toast 13 : DRY
Toast 13 : BUTTERED
Toast 13 : JAMMED
Toast 14 : DRY
Toast 14 : BUTTERED
Toast 14 : JAMMED
Toast 15 : DRY
Toast 15 : BUTTERED
Toast 15 : JAMMED
Toast 16 : DRY
Toast 16 : BUTTERED
Toast 16 : JAMMED
Toast 17 : DRY
Toast 17 : BUTTERED
Toast 17 : JAMMED
Toast 18 : DRY
Toast 18 : BUTTERED
Toast 18 : JAMMED
Toast 19 : DRY
Toast 19 : BUTTERED
Toast 19 : JAMMED
Toast 20 : DRY
Toast 20 : BUTTERED
Toast 20 : JAMMED
Toast 21 : DRY
Toast 21 : BUTTERED
Toast 21 : JAMMED
Toast 22 : DRY
Toast 22 : BUTTERED
Toast 22 : JAMMED
Toast 23 : DRY
Toast 23 : BUTTERED
Toast 23 : JAMMED
Toast 24 : DRY
Toast 24 : BUTTERED
Toast 24 : JAMMED
Toast 25 : DRY
Toast 25 : BUTTERED
Toast 25 : JAMMED
Toast 26 : DRY
Toast 26 : BUTTERED
Toast 26 : JAMMED
Toast 27 : DRY
Toast 27 : BUTTERED
Toast 27 : JAMMED
Toast 28 : DRY
Toast 28 : BUTTERED
Toast 28 : JAMMED
Toast 29 : DRY
Toast 29 : BUTTERED
Toast 29 : JAMMED
Toast 30 : DRY
Toast 30 : BUTTERED
Toast 30 : JAMMED
Toast 31 : DRY
Toast 31 : BUTTERED
Toast 31 : JAMMED
Toast 32 : DRY
Toast 32 : BUTTERED
Toast 32 : JAMMED
Toast 33 : DRY
Toast 33 : BUTTERED
Toast 33 : JAMMED
Jammer interrupted
Jammer off
Butterer interrupted
Butterer off
Toaster interrupted
Toaster off

  4. Toast是一个使用enum值的优秀示例。注意,这个示例中没有任何显式的同步(即使用Lock对象或synchronized关键字的同步),因为同步由队列(其内部是同步的)和系统的设计隐式地管理了 ------ 每片Toast在任何时刻都只由一个任务在操作。因为队列的阻塞,使得处理过程将被自动地挂起和恢复。你可以看到由BlockingQueue产生的简化十分明显。在使用显示的wait()和notifyAll()时存在的类和类之间的耦合被消除了,因为每个类都只和它的BlockingQueue通信。

  5.  鸣谢

    LinkedBlockingQueue源码分析(JDK8)

    LinkedBlockingQueue源码分析

  6. 啦啦啦

TIJ -- 吐司BlockingQueue的更多相关文章

  1. java 线程 生产者-消费者与队列,任务间使用管道进行输入、输出 解说演示样例 --thinking java4

    package org.rui.thread.block2; import java.io.BufferedReader; import java.io.IOException; import jav ...

  2. 建房子之前先挖地基 - Java BlockingQueue理解

    最近一直在看<Think In Java>里关于并发部分的章节,读到第二十一章有一个有趣的比喻:必须先挖房子的地基,但是接下来可以并行的铺设钢结构和构建水泥部件,而这两项任务必须在混凝土浇 ...

  3. 加深一下BlockingQueue的认识

    认识BlockingQueue BlockingQueue是一种可以阻塞线程的队列,java中对这种队列提供了方法抽象,BlockingQueue则是抽象的接口. add:添加元素到队列里,添加成功返 ...

  4. 阅读ArrayBlockingQueue源码了解如何利用锁实现BlockingQueue

    BlockingQueue是多线程里面一个非常重要的数据结构.在面试的时候,也常会被问到怎么实现BlockingQueue.本篇根据Java7里ArrayBlockingQueue的源码,简单介绍一下 ...

  5. BlockingQueue 阻塞队列,很有用的一种

    BlockingQueue的核心方法:放入数据: offer(anObject):表示如果可能的话,将anObject加到BlockingQueue里,即如果BlockingQueue可以容纳, 则返 ...

  6. BlockingQueue使用

    import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import ja ...

  7. [JAVA] BlockingQueue学习

    有点时间,巩固巩固下基础知识:BlockingQueue,如果BlockQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤 ...

  8. BlockingQueue深入分析(转)

    1.BlockingQueue定义的常用方法如下   抛出异常 特殊值 阻塞 超时 插入 add(e) offer(e) put(e) offer(e,time,unit) 移除 remove() p ...

  9. 多线程编程-工具篇-BlockingQueue

    在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序 ...

随机推荐

  1. Cocos Creator 节点

    //节点从创建到节点挂载一些过程 1.JS中节点使用: a.创建:在properties中定义节点(可能包括节点的默认值和类型): b.挂载:在相应的方法中获取节点获取相应节点,挂载到父元素 例== ...

  2. xpath分析 html文件抽正文的过程

    使用Py3的HTMLParser解析模块解析HTML的时候,出现:no moudle named 'markupbase' 错误. 用xpath打算分析html里面的新闻.根据运行程序后的报错的信息, ...

  3. 四方定理(递归) --java

    四方定理 数论中有著名的四方定理:所有自然数至多只要用四个数的平方和就可以表示. 我们可以通过计算机验证其在有限范围的正确性. import java.*; import java.util.*; p ...

  4. Windows平台下SVN安装配置及使用

    原文链接:https://www.cnblogs.com/snake-hand/archive/2013/06/09/3130022.html,等有空了玩一玩吧,现在没空.

  5. Mac安装Linux的KVM管理工具virt-manager

    安装: brew tap jeffreywildman/homebrew-virt-manager brew install virt-manager virt-viewer 中途会碰到很多问题,可以 ...

  6. javaScript系列 [01]-javaScript函数基础

    [01]-javaScript函数基础 1.1 函数的创建和结构 函数的定义:函数是JavaScript的基础模块单元,包含一组语句,用于代码复用.信息隐蔽和组合调用. 函数的创建:在javaScri ...

  7. Spring Boot tomcat

    定制内嵌 Tomcat 设置内嵌Tomcat的端口 Spring Boot 内嵌的 Tomcat 服务器默认运行在 8080 端口.如果,我们需要修改Tomcat的端口,我们可以在 src/main/ ...

  8. Eslint 规则说明

    "no-alert": 0,//禁止使用alert confirm prompt"no-array-constructor": 2,//禁止使用数组构造器&qu ...

  9. 网络协议学习(2)---IP地址

    一.IPv4地址 IPv4地址为32bit地址,分为5类(ABCDE,这里不讨论特殊用途的D和E类). 通常我们八位一看,写成4个部分,例如:00000000 00000000 00000000 00 ...

  10. 找不到指定的 VM 安装:类型 标准 VM,名称 jre7

    问题背景是这样 原来使用的是jre7.0.55,后来为了安装使用 layabox IDE ,然后装了jdk_8u144 之后需要切换环境变量 之后java项目调试的时候重新设置了jdk,没问题. 直到 ...