吐司BlockingQueue

来源:互联网 发布:网上直销软件 编辑:程序博客网 时间:2024/04/27 17:44

有一台机器具有三个任务:一个制作吐司、一个给吐司摸黄油、另一个在抹过黄油的吐司上涂果酱。我们可以通过各个处理过程之间的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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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();}}


0 0