吐司BlockingQueue

有一台机器具有三个任务:一个制作吐司、一个给吐司摸黄油、另一个在抹过黄油的吐司上涂果酱。我们可以通过各个处理过程之间的BlockingQueue来运行这个吐司制作程序。也就说我们可以利用三个线程安全的阻塞队列LinkedBlockingQueue,一个任务完成后就把这个Toast放到下一个队列中,维护三个队列就能做到了。

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;
	}

	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {
				TimeUnit.MILLISECONDS.sleep(100 + rand.nextInt(500));
				Toast t = new Toast(count++);
				System.out.println(t);
				toastQueue.put(t);
			}
		} catch (InterruptedException e) {
			System.out.println("Toaster interrupted");
		}
		System.out.println("Toaster off");
	}
}

class Butterer implements Runnable {
	private ToastQueue dryQueue, butteredQueue;
	public Butterer(ToastQueue dry, ToastQueue buttered) {
		this.dryQueue = dry;
		this.butteredQueue = buttered;
	}

	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {

					Toast t = this.dryQueue.take();
					t.butter();
					System.out.println(t);
					butteredQueue.put(t);

			}
		} catch (InterruptedException e) {
				System.out.println("Butterer interrputed");
			}
		System.out.println("Butterer off");
	}
}

class Jammer implements Runnable {
	private ToastQueue butteredQueue, finishedQueue;
	public Jammer(ToastQueue buttered, ToastQueue finished) {
		this.butteredQueue = buttered;
		this.finishedQueue = finished;
	}

	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {
				Toast t = butteredQueue.take();
				t.jam();
				System.out.println(t);
				finishedQueue.add(t);
			}
		} catch (InterruptedException e) {
			System.out.println("Jammer interrupted");
		}
		System.out.println("Jammer off");
	}
}

class Eater implements Runnable {
	private ToastQueue finishedQueue;
	private int counter = 0;
	public Eater(ToastQueue finished) {
		this.finishedQueue = finished;
	}
	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {
				Toast t = finishedQueue.take();
				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 Exception{
		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));
		exec.execute(new Eater(finishedQueue));
		TimeUnit.SECONDS.sleep(5);
		exec.shutdownNow();
	}
}
时间: 2024-08-02 02:42:41

吐司BlockingQueue的相关文章

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;

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

package org.rui.thread.block2; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedB

考虑下面这个使用Blocki

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;

BlockingQueue(阻塞队列)详解

一. 前言 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景. 二. 认识BlockingQueue 阻塞队列,顾名思义,首先它是一个队列,而一个队列在数据结构中所起的作用大致如下图所示: 从上图我们可以很清楚看到,通过一个共享的队列,可以使得数据由

深入浅出 Java Concurrency (22): 并发容器 part 7 可阻塞的BlockingQueue (2)[转]

在上一节中详细分析了LinkedBlockingQueue 的实现原理.实现一个可扩展的队列通常有两种方式:一种方式就像LinkedBlockingQueue一样使用链表,也就是每一个元素带有下一个元素的引用,这样的队列原生就是可扩展的:另外一种就是通过数组实现,一旦队列的大小达到数组的容量的时候就将数组扩充一倍(或者一定的系数倍),从而达到扩容的目的.常见的ArrayList就属于第二种.前面章节介绍过的HashMap确是综合使用了这两种方式. 对于一个Queue而言,同样可以使用数组实现.使

spring线程池ThreadPoolTaskExecutor与阻塞队列BlockingQueue

一: ThreadPoolTaskExecutor是一个spring的线程池技术,查看代码可以看到这样一个字段: private ThreadPoolExecutor threadPoolExecutor; 可以发现,spring的  ThreadPoolTaskExecutor是使用的jdk中的java.util.concurrent.ThreadPoolExecutor进行实现, 直接看代码: @Override protected ExecutorService initializeExe

手机卫士07_自定义吐司_桌面小火箭_短信备份_接口和回调_应用程序信息,

1,自定义吐司显示风格 ①创建一个布局文件(代码注册的View看不出效果,所以还是定义布局文件比较好) 这里的背景是.9图片会根据包裹内容来拉伸 ②在显示自定义吐司的界面,显示的吐司通过View.inflate()创建 ③在设置中心增加一条修改归属地显示风格. {"半透明","活力橙","卫士蓝","金属灰","苹果绿"}; 点击之后弹出一个单选对话框. builder.setSingleChoiceIte

手机卫士06_挂电话拦截短信,资产目录_来电去电_自定义吐司

1.1 反射调用系统隐藏api挂掉电话 Android 1.5之前可以通过 TelephonyManager,tm.endCall();//但是列表找不到 谷歌认为挂掉电话是危及手机根本功能的动作,所以隐藏了这个api 在1.5之后,要通过反射调用这一api才能实现 两个网站 ①www.greocide.com //搜索源码的网站 搜索TelephonyManager,查找版本最低的版本即可(越低越容易理解) 这个api被隐藏掉了,不能直接获取到TelephonyManager.对象. ②通过g

使用BlockingQueue的生产者消费者模式

BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.使用场景. 首先它是一个队列,而一个队列在数据结构中所起的作用大致如下图所示: 通过一个共享的队列,可以使得数据由队列的一端输入,从另外一端输出:在生产者消费者模式中,通过队列的方式可以很方便的实现两者之间的数据共享.强大的BlockingQueue使我们不用关心什么时候需要阻塞线程,什么时候需要唤醒线程. BlockingQueue的