阻塞队列(BlockingQueue)实现生产者消费者
2020-03-03 本文已影响0人
繁书_
本例参照<<Java编程思想第21章>>
- 此例为吐司制作过程,一天机器具有三个任务,一个制作吐司,一个给吐司抹黄油,一个给吐司抹果酱,通过BlockingQueue来处理格格过程
class Toast{
public enum Status{DRY,BUTTERED, JAMMED,}
public Status status = Status.DRY;
private final int id;
public Toast(int id) {
this.id = id;
}
public void butter() {
status = Status.BUTTERED;
}
public void jam() {
status = Status.JAMMED;
}
public Status getStatus() {
return status;
}
public int getId() {
return id;
}
@Override
public String toString() {
return "Toast{" +
"status=" + status +
", id=" + id +
'}';
}
}
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 toastQueue) {
this.toastQueue = toastQueue;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
TimeUnit.MILLISECONDS.sleep(100 + rand.nextInt(500));
Toast toast = new Toast(count++);
System.out.println(toast);
toastQueue.put(toast);
}
} catch (Exception e) {
System.out.println("Toaster interrupted");
}
System.out.println("Toaster off");
}
}
class Butterer implements Runnable{
private ToastQueue dryQueue, butteredQueue;
public Butterer(ToastQueue dryQueue, ToastQueue butteredQueue) {
this.dryQueue = dryQueue;
this.butteredQueue = butteredQueue;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
Toast toast = dryQueue.take();
toast.butter();
System.out.println(toast);
butteredQueue.put(toast);
}
} catch (Exception e) {
System.out.println("Butterer off");
}
}
}
class Jammer implements Runnable{
private ToastQueue butterQueue, finishQueue;
public Jammer(ToastQueue butterQueue, ToastQueue finishQueue) {
this.butterQueue = butterQueue;
this.finishQueue = finishQueue;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
Toast t = butterQueue.take();
t.jam();
System.out.println(t);
finishQueue.put(t);
}
} catch (Exception 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 finishedQueue) {
this.finishedQueue = finishedQueue;
}
@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 (Exception 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();
ToastQueue butterQueue = new ToastQueue();
ToastQueue finishQueue = new ToastQueue();
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Toaster(dryQueue));
exec.execute(new Butterer(dryQueue, butterQueue));
exec.execute(new Jammer(butterQueue, finishQueue));
exec.execute(new Eater(finishQueue));
TimeUnit.SECONDS.sleep(5);
exec.shutdown();
}
}