本程序是thinking in java 4th的课后练习题,通过Java SE5的BlockingQueue来解决生产者与消费者的问题。通过BlockingQueue可以实现解耦。每个类都有自己的BlockingQueue通信。
package concurrency;
//: concurrency/ToastOMatic.java
// A toaster that uses queues.
import java.util.concurrent.*;
import java.util.*;
import static net.mindview.util.Print.*;
class Toast {
public enum Status {
DRY, BUTTERED, JAMMED, JELLY
}
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 void jelly() {
status = Status.JELLY;
}
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(500));
// Make toast
Toast t = new Toast(count++);
print(t);
// Insert into queue
toastQueue.put(t);
}
} catch (InterruptedException e) {
print(”Toaster interrupted”);
}
print(”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();
print(t);
butteredQueue.put(t);
}
} catch (InterruptedException e) {
print(”Butterer interrupted”);
}
print(”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();
print(t);
finishedQueue.put(t);
}
} catch (InterruptedException e) {
print(”Jammer interrupted”);
}
print(”Jammer off”);
}
}
//向土司里面加果冻
class Jelly implements Runnable {
private ToastQueue finishedQueue, jammerQueue;
Jelly(ToastQueue finishedQueue, ToastQueue jammerQueue) {
this.finishedQueue = finishedQueue;
this.jammerQueue = jammerQueue;
}
public void run() {
try {
while (!Thread.interrupted()) {
Toast jam = jammerQueue.take();
jam.jelly();
print(jam);
finishedQueue.add(jam);
}
} catch (InterruptedException ex) {
print(”Jelly off!”);
}
}
}
//制作混合土司
class MixToast {
ExecutorService exec = Executors.newCachedThreadPool();
ToastQueue dryQueue = new ToastQueue(),
butteredQueue = new ToastQueue(),
jammerQueue = new ToastQueue();
public ToastQueue makeMixToast() {
exec.execute(new Toaster(dryQueue));
exec.execute(new Butterer(dryQueue, butteredQueue));
exec.execute(new Jammer(butteredQueue, jammerQueue));
return jammerQueue;
}
public void shutDownNow() {
exec.shutdownNow();
}
}
// Consume the toast:
class Eater implements Runnable {
private ToastQueue finishedQueue;
private int counter = 0;
public Eater(ToastQueue finished) {
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.JELLY) {
print(”>>>> Error: ” + t);
System.exit(1);
} else {
print(”Chomp! ” + t);
}
}
} catch (InterruptedException e) {
print(”Eater interrupted”);
}
print(”Eater off”);
}
}
public class ToastOMatic {
public static void main(String[] args) throws Exception {
ToastQueue jammerQueue;
ToastQueue finishedQueue = new ToastQueue();
ExecutorService exec = Executors.newCachedThreadPool();
MixToast m=new MixToast();
jammerQueue = m.makeMixToast();
exec.execute(new Jelly(finishedQueue, jammerQueue));
exec.execute(new Eater(finishedQueue));
TimeUnit.SECONDS.sleep(5);
m.shutDownNow();
exec.shutdownNow();
}
} /* (Execute to see output) *///:~
October 21st, 2008 |