1. 吐司BlockingQueue

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

  2. class :

  1. package lime.thinkingInJava._021._005._004;
  2.  
  3. import com.sun.corba.se.impl.oa.toa.TOA;
  4.  
  5. import java.util.Random;
  6. import java.util.concurrent.ExecutorService;
  7. import java.util.concurrent.Executors;
  8. import java.util.concurrent.LinkedBlockingQueue;
  9. import java.util.concurrent.TimeUnit;
  10.  
  11. /**
  12. * @Author : Lime
  13. * @Description :
  14. * @Remark :
  15. */
  16. class Toast{
  17. public enum Status{DRY,BUTTERED,JAMMED}
  18. private Status status = Status.DRY;
  19. private final int id;
  20. public Toast(int idn){id = idn;}
  21. public void butter(){
  22. status = Status.BUTTERED;
  23. }
  24. public void jam(){
  25. status = Status.JAMMED;
  26. }
  27. public Status getStatus(){
  28. return status;
  29. }
  30. public int getId(){
  31. return id;
  32. }
  33. public String toString(){
  34. return "Toast " + id + " : " + status;
  35. }
  36. }
  37. class ToastQueue extends LinkedBlockingQueue<Toast>{}
  38.  
  39. class Toaster implements Runnable{
  40. private ToastQueue toastQueue;
  41. private int count = 0;
  42. private Random rand = new Random(47);
  43. public Toaster(ToastQueue tq){
  44. toastQueue = tq;
  45. }
  46. public void run(){
  47. try{
  48. while (!Thread.interrupted()){
  49. TimeUnit.MILLISECONDS.sleep(100 + rand.nextInt(100));
  50. //Make toast
  51. Toast t = new Toast(count++);
  52. System.out.println(t);
  53. //Insert into queue
  54. toastQueue.put(t);
  55. }
  56. } catch (InterruptedException e) {
  57. System.out.println("Toaster interrupted");
  58. }
  59. System.out.println("Toaster off");
  60. }
  61. }
  62. //Apply butter to toast
  63. class Butterer implements Runnable{
  64. private ToastQueue dryQueue ,butteredQueue;
  65. public Butterer(ToastQueue dry , ToastQueue buttered){
  66. dryQueue = dry;
  67. butteredQueue = buttered;
  68. }
  69. public void run(){
  70. try{
  71. while (!Thread.interrupted()){
  72. //Blocks until next piece of toast is available;
  73. Toast t = dryQueue.take();
  74. t.butter();
  75. System.out.println(t);
  76. butteredQueue.put(t);
  77. }
  78. } catch (InterruptedException e) {
  79. System.out.println("Butterer interrupted");
  80. }
  81. System.out.println("Butterer off");
  82. }
  83. }
  84. //Apply jam to buttered toast;
  85. class Jammer implements Runnable{
  86. private ToastQueue butteredQueue,finishedQueue;
  87. public Jammer(ToastQueue buttered,ToastQueue finished){
  88. butteredQueue = buttered;
  89. finishedQueue = finished;
  90. }
  91. public void run(){
  92. try{
  93. while (!Thread.interrupted()){
  94. //Blocks until next piece of toast is available;
  95. Toast t = butteredQueue.take();
  96. t.jam();
  97. System.out.println(t);
  98. finishedQueue.put(t);
  99. }
  100. } catch (InterruptedException e) {
  101. System.out.println("Jammer interrupted");
  102. }
  103. System.out.println("Jammer off");
  104. }
  105. }
  106. //Consume the toast;
  107. class Eater implements Runnable{
  108. private ToastQueue finishedQueue;
  109. private int counter = 0;
  110. public Eater(ToastQueue finished){
  111. this.finishedQueue = finished;
  112. }
  113. public void run(){
  114. try{
  115. while (!Thread.interrupted()){
  116. //Blocks until next piece of toast is available;
  117. Toast t = finishedQueue.take();
  118. //Verify that the toast is coming in order;
  119. //and that all pieces are getting jammed;
  120. if(t.getId() != counter++ || t.getStatus() != Toast.Status.JAMMED){
  121. System.out.println(">>>> Error : " + t);
  122. System.exit(1);
  123. }else{
  124. System.out.println("Chomp ! " + t);
  125. }
  126. }
  127. } catch (InterruptedException e) {
  128. System.out.println("Eater interrupted");
  129. }
  130. System.out.println("Eater off");
  131. }
  132. }
  133. public class ToastOMatic {
  134. public static void main(String[] args) throws InterruptedException {
  135. ToastQueue dryQueue = new ToastQueue(),
  136. butteredQueue = new ToastQueue(),
  137. finishedQueue = new ToastQueue();
  138. ExecutorService exec = Executors.newCachedThreadPool();
  139. exec.execute(new Toaster(dryQueue));
  140. exec.execute(new Butterer(dryQueue,butteredQueue));
  141. exec.execute(new Jammer(butteredQueue,finishedQueue));
  142. TimeUnit.SECONDS.sleep(5);
  143. exec.shutdownNow();
  144. }
  145. }

  3. Console :

  1. Toast 0 : DRY
  2. Toast 0 : BUTTERED
  3. Toast 0 : JAMMED
  4. Toast 1 : DRY
  5. Toast 1 : BUTTERED
  6. Toast 1 : JAMMED
  7. Toast 2 : DRY
  8. Toast 2 : BUTTERED
  9. Toast 2 : JAMMED
  10. Toast 3 : DRY
  11. Toast 3 : BUTTERED
  12. Toast 3 : JAMMED
  13. Toast 4 : DRY
  14. Toast 4 : BUTTERED
  15. Toast 4 : JAMMED
  16. Toast 5 : DRY
  17. Toast 5 : BUTTERED
  18. Toast 5 : JAMMED
  19. Toast 6 : DRY
  20. Toast 6 : BUTTERED
  21. Toast 6 : JAMMED
  22. Toast 7 : DRY
  23. Toast 7 : BUTTERED
  24. Toast 7 : JAMMED
  25. Toast 8 : DRY
  26. Toast 8 : BUTTERED
  27. Toast 8 : JAMMED
  28. Toast 9 : DRY
  29. Toast 9 : BUTTERED
  30. Toast 9 : JAMMED
  31. Toast 10 : DRY
  32. Toast 10 : BUTTERED
  33. Toast 10 : JAMMED
  34. Toast 11 : DRY
  35. Toast 11 : BUTTERED
  36. Toast 11 : JAMMED
  37. Toast 12 : DRY
  38. Toast 12 : BUTTERED
  39. Toast 12 : JAMMED
  40. Toast 13 : DRY
  41. Toast 13 : BUTTERED
  42. Toast 13 : JAMMED
  43. Toast 14 : DRY
  44. Toast 14 : BUTTERED
  45. Toast 14 : JAMMED
  46. Toast 15 : DRY
  47. Toast 15 : BUTTERED
  48. Toast 15 : JAMMED
  49. Toast 16 : DRY
  50. Toast 16 : BUTTERED
  51. Toast 16 : JAMMED
  52. Toast 17 : DRY
  53. Toast 17 : BUTTERED
  54. Toast 17 : JAMMED
  55. Toast 18 : DRY
  56. Toast 18 : BUTTERED
  57. Toast 18 : JAMMED
  58. Toast 19 : DRY
  59. Toast 19 : BUTTERED
  60. Toast 19 : JAMMED
  61. Toast 20 : DRY
  62. Toast 20 : BUTTERED
  63. Toast 20 : JAMMED
  64. Toast 21 : DRY
  65. Toast 21 : BUTTERED
  66. Toast 21 : JAMMED
  67. Toast 22 : DRY
  68. Toast 22 : BUTTERED
  69. Toast 22 : JAMMED
  70. Toast 23 : DRY
  71. Toast 23 : BUTTERED
  72. Toast 23 : JAMMED
  73. Toast 24 : DRY
  74. Toast 24 : BUTTERED
  75. Toast 24 : JAMMED
  76. Toast 25 : DRY
  77. Toast 25 : BUTTERED
  78. Toast 25 : JAMMED
  79. Toast 26 : DRY
  80. Toast 26 : BUTTERED
  81. Toast 26 : JAMMED
  82. Toast 27 : DRY
  83. Toast 27 : BUTTERED
  84. Toast 27 : JAMMED
  85. Toast 28 : DRY
  86. Toast 28 : BUTTERED
  87. Toast 28 : JAMMED
  88. Toast 29 : DRY
  89. Toast 29 : BUTTERED
  90. Toast 29 : JAMMED
  91. Toast 30 : DRY
  92. Toast 30 : BUTTERED
  93. Toast 30 : JAMMED
  94. Toast 31 : DRY
  95. Toast 31 : BUTTERED
  96. Toast 31 : JAMMED
  97. Toast 32 : DRY
  98. Toast 32 : BUTTERED
  99. Toast 32 : JAMMED
  100. Toast 33 : DRY
  101. Toast 33 : BUTTERED
  102. Toast 33 : JAMMED
  103. Jammer interrupted
  104. Jammer off
  105. Butterer interrupted
  106. Butterer off
  107. Toaster interrupted
  108. 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. Python中将array类型不按科学计数法存在文件中的方法

    直接上代码: from numpy import *import numpy as npDrug_array = zeros((708,708),dtype = int)f = open('D:\ma ...

  2. Vue(七)发送Ajax请求

    发送AJAX请求 1. 简介 vue本身不支持发送AJAX请求,需要使用vue-resource.axios等插件实现 axios是一个基于Promise的HTTP请求客户端,用来发送请求,也是vue ...

  3. GMA Round 1 大吉大利,晚上吃鸡

    传送门 大吉大利,晚上吃鸡 新年走亲访友能干点啥呢,咱开黑吃鸡吧. 这里有32个人,每个人都可能想玩或者不想玩,这样子一共有$2^{32}$种可能.而要开黑当然得4人4人组一队(四人模式),所以说如果 ...

  4. Intel处理器技术文档

    1.intel程序员手册(1986).pdf 下载地址 2.Intel® 64 and IA-32 Architectures Software Developer Manuals   下载链接 3. ...

  5. iOS链接库的冲突

    最近在打包的时候,遇到一个坑.特此记录一下 起因是发现 Unity 5.4 版本,使用c#写的下载,下载速度无法突破 2M/s,同样的网络,后来横向对比使用原来 Cocos2d 开始的游戏,可以达到 ...

  6. HRD Emulator in HTML5

    Posted on March 21, 2012 by Moto Just like MPEG-2 video uses VBV (Video Buffer Verifier), H.264 stan ...

  7. windows下Graphviz安装及入门教程

    下载安装配置环境变量 intall 配置环境变量 验证 基本绘图入门 graph digraph 一个复杂的例子 和python交互 发现好的工具,如同发现新大陆.有时,我们会好奇,论文中.各种专业的 ...

  8. jvm理论-字节码指令

    Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成. 基本数据类型 1.除了l ...

  9. Linux中添加计划任务与Elasticsearch日志自动清理

    一.简述 当日志发送到ELK之后,Elasticsearch随着日志的增加,占用磁盘量会越来越大.这时候,需要我们写角本定期DELETE日志.角本写法,也很简单,只是发送HTTP的DELETE方式到: ...

  10. 【Linux】关于ffmpeg的一些常见用法

    一.FFmpeg简介 FFmpeg是一款非常快速的视频和音频转换器, 是开源项目 FFmpeg (Fast Forward moving pictures expert group) 的命令行程序. ...