Java中BlcokingQueue的使用

直接上Thinking in Java 4th 的例子:
class MyUntil {
	static void print(String str) {
		System.out.println(str);
	}
}

class Toast {
	public enum Status {
		DRY, BUTTERED, JAMED
	}

	private 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.JAMED;
	}

	public Status getStatus() {
		return status;
	}

	public int getId() {
		return id;
	}

	@Override
	public String toString() {
		return "Toast " + id + ": " + status;
	}
}

class ToastQueue extends LinkedBlockingQueue<Toast> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

}

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));
				Toast t = new Toast(count++);
				MyUntil.print(t.toString());
				toastQueue.put(t);
			}
		} catch (InterruptedException e) {
			MyUntil.print("Toaster interrupted");
		}
		MyUntil.print("Toaster off");
	}
}

class Butterer implements Runnable {
	private ToastQueue dryQueue, butterQueue;

	public Butterer(ToastQueue dry, ToastQueue buttered) {
		dryQueue = dry;
		butterQueue = buttered;
	}

	public void run() {
		try {
			while (!Thread.interrupted()) {
				Toast t = dryQueue.take();
				t.butter();
				MyUntil.print(t.toString());
				butterQueue.put(t);
			}
		} catch (InterruptedException e) {
			MyUntil.print("Butterer interrupted");
		}
		MyUntil.print("Butter off");
	}
}

class Jammer implements Runnable {
	private ToastQueue butteredQueue, finishedQueue;

	public Jammer(ToastQueue buttered, ToastQueue finished) {
		butteredQueue = buttered;
		finishedQueue = finished;
	}

	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {
				Toast t = butteredQueue.take();
				t.jam();
				MyUntil.print(t.toString());
				finishedQueue.put(t);
			}
		} catch (InterruptedException e) {
			MyUntil.print("Jammer Interruped ");
		}
		MyUntil.print("Jammer off");
	}
}

class ToastEater implements Runnable {
	private ToastQueue finishedQueue;
	private int counter = 0;

	public ToastEater(ToastQueue finished) {
		finishedQueue = finished;
	}

	public void run() {
		try {
			while (!Thread.interrupted()) {
				Toast t = finishedQueue.take();
				if (t.getId() != counter++
						|| t.getStatus() != Toast.Status.JAMED) {
					MyUntil.print(">>>>>>>>Error: " + t.toString());
					System.exit(1);
				} else {
					MyUntil.print("Chomp! " + t);
					MyUntil.print("\n");
				}
			}
		} catch (InterruptedException e) {
			MyUntil.print("Eater interrupted !");
		}
		MyUntil.print("Eater off");
	}
}

public class ToastMatic {
	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 ToastEater(finishedQueue));
		exec.execute(new Toaster(dryQueue));
		exec.execute(new Butterer(dryQueue, butteredQueue));
		exec.execute(new Jammer(butteredQueue, finishedQueue));

		TimeUnit.SECONDS.sleep(5);
		exec.shutdownNow();
	}
}


BlockingQueue提供了一种便捷的方式处理资源共享, 从而避免了用synchronized带来的繁琐, 以及用synchronized方法带来的死锁。


输出结果
Toast 0: DRY
Toast 0: BUTTERED
Toast 0: JAMED
Chomp! Toast 0: JAMED


Toast 1: DRY
Toast 1: BUTTERED
Toast 1: JAMED
Chomp! Toast 1: JAMED


Toast 2: DRY
Toast 2: BUTTERED
Toast 2: JAMED
Chomp! Toast 2: JAMED


Toast 3: DRY
Toast 3: BUTTERED
Toast 3: JAMED
Chomp! Toast 3: JAMED


Toast 4: DRY
Toast 4: BUTTERED
Toast 4: JAMED
Chomp! Toast 4: JAMED


Toast 5: DRY
Toast 5: BUTTERED
Toast 5: JAMED
Chomp! Toast 5: JAMED


Toast 6: DRY
Toast 6: BUTTERED
Toast 6: JAMED
Chomp! Toast 6: JAMED


Toast 7: DRY
Toast 7: BUTTERED
Toast 7: JAMED
Chomp! Toast 7: JAMED


Toast 8: DRY
Toast 8: BUTTERED
Toast 8: JAMED
Chomp! Toast 8: JAMED


Toast 9: DRY
Toast 9: BUTTERED
Toast 9: JAMED
Chomp! Toast 9: JAMED


Toast 10: DRY
Toast 10: BUTTERED
Toast 10: JAMED
Chomp! Toast 10: JAMED


Toast 11: DRY
Toast 11: BUTTERED
Toast 11: JAMED
Chomp! Toast 11: JAMED


Toast 12: DRY
Toast 12: BUTTERED
Toast 12: JAMED
Chomp! Toast 12: JAMED


Toast 13: DRY
Toast 13: BUTTERED
Toast 13: JAMED
Chomp! Toast 13: JAMED


Toast 14: DRY
Toast 14: BUTTERED
Toast 14: JAMED
Chomp! Toast 14: JAMED


Eater interrupted !
Eater off
Jammer Interruped 
Jammer off
Butterer interrupted
Butter off
Toaster interrupted
Toaster off

你可能感兴趣的:(Java中BlcokingQueue的使用)