TIJ -- 吐司BlockingQueue
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. 鸣谢
6. 啦啦啦
TIJ -- 吐司BlockingQueue的更多相关文章
- java 线程 生产者-消费者与队列,任务间使用管道进行输入、输出 解说演示样例 --thinking java4
package org.rui.thread.block2; import java.io.BufferedReader; import java.io.IOException; import jav ...
- 建房子之前先挖地基 - Java BlockingQueue理解
最近一直在看<Think In Java>里关于并发部分的章节,读到第二十一章有一个有趣的比喻:必须先挖房子的地基,但是接下来可以并行的铺设钢结构和构建水泥部件,而这两项任务必须在混凝土浇 ...
- 加深一下BlockingQueue的认识
认识BlockingQueue BlockingQueue是一种可以阻塞线程的队列,java中对这种队列提供了方法抽象,BlockingQueue则是抽象的接口. add:添加元素到队列里,添加成功返 ...
- 阅读ArrayBlockingQueue源码了解如何利用锁实现BlockingQueue
BlockingQueue是多线程里面一个非常重要的数据结构.在面试的时候,也常会被问到怎么实现BlockingQueue.本篇根据Java7里ArrayBlockingQueue的源码,简单介绍一下 ...
- BlockingQueue 阻塞队列,很有用的一种
BlockingQueue的核心方法:放入数据: offer(anObject):表示如果可能的话,将anObject加到BlockingQueue里,即如果BlockingQueue可以容纳, 则返 ...
- BlockingQueue使用
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import ja ...
- [JAVA] BlockingQueue学习
有点时间,巩固巩固下基础知识:BlockingQueue,如果BlockQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤 ...
- BlockingQueue深入分析(转)
1.BlockingQueue定义的常用方法如下 抛出异常 特殊值 阻塞 超时 插入 add(e) offer(e) put(e) offer(e,time,unit) 移除 remove() p ...
- 多线程编程-工具篇-BlockingQueue
在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序 ...
随机推荐
- Python中将array类型不按科学计数法存在文件中的方法
直接上代码: from numpy import *import numpy as npDrug_array = zeros((708,708),dtype = int)f = open('D:\ma ...
- Vue(七)发送Ajax请求
发送AJAX请求 1. 简介 vue本身不支持发送AJAX请求,需要使用vue-resource.axios等插件实现 axios是一个基于Promise的HTTP请求客户端,用来发送请求,也是vue ...
- GMA Round 1 大吉大利,晚上吃鸡
传送门 大吉大利,晚上吃鸡 新年走亲访友能干点啥呢,咱开黑吃鸡吧. 这里有32个人,每个人都可能想玩或者不想玩,这样子一共有$2^{32}$种可能.而要开黑当然得4人4人组一队(四人模式),所以说如果 ...
- Intel处理器技术文档
1.intel程序员手册(1986).pdf 下载地址 2.Intel® 64 and IA-32 Architectures Software Developer Manuals 下载链接 3. ...
- iOS链接库的冲突
最近在打包的时候,遇到一个坑.特此记录一下 起因是发现 Unity 5.4 版本,使用c#写的下载,下载速度无法突破 2M/s,同样的网络,后来横向对比使用原来 Cocos2d 开始的游戏,可以达到 ...
- HRD Emulator in HTML5
Posted on March 21, 2012 by Moto Just like MPEG-2 video uses VBV (Video Buffer Verifier), H.264 stan ...
- windows下Graphviz安装及入门教程
下载安装配置环境变量 intall 配置环境变量 验证 基本绘图入门 graph digraph 一个复杂的例子 和python交互 发现好的工具,如同发现新大陆.有时,我们会好奇,论文中.各种专业的 ...
- jvm理论-字节码指令
Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成. 基本数据类型 1.除了l ...
- Linux中添加计划任务与Elasticsearch日志自动清理
一.简述 当日志发送到ELK之后,Elasticsearch随着日志的增加,占用磁盘量会越来越大.这时候,需要我们写角本定期DELETE日志.角本写法,也很简单,只是发送HTTP的DELETE方式到: ...
- 【Linux】关于ffmpeg的一些常见用法
一.FFmpeg简介 FFmpeg是一款非常快速的视频和音频转换器, 是开源项目 FFmpeg (Fast Forward moving pictures expert group) 的命令行程序. ...