朋友Every今天问我,线程到底怎么控制?消费者模式怎么写?
于是,我给他写了一个生产消费蛋糕的例子 ,贴出来分享一下。
/**
* 演示消费者模式
*/
package com.godway.custom;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* @author 高伟
* @date Jan 6, 2012 1:40:07 PM
* @description:
*
* 演示蛋糕的生产过程。
*/
public class CakeExample {
public static void main(String[] args) {
/**
* 池子
* 蛋糕箱子
* 所有机器产生的蛋糕都放到这里
* 所有人吃蛋糕都从这里取
*
* ConcurrentLinkedQueue:采用线程同步的队列
*/
ConcurrentLinkedQueue<Cake> cakeList = new ConcurrentLinkedQueue<Cake>();
/**
* 生产者
* 机器,生产蛋糕
* 五个工厂应该够咱俩吃
*/
Machine machine1 = new Machine ("machine1",cakeList);
Machine machine2 = new Machine ("machine2",cakeList);
Machine machine3 = new Machine ("machine3",cakeList);
Machine machine4 = new Machine ("machine4",cakeList);
Machine machine5 = new Machine ("machine5",cakeList);
/**
* 消费者
* 人,吃蛋糕
*/
Person gaogao = new Person("gaogao",cakeList);
Person every = new Person("every",cakeList);
/**
* 启动
*/
new Thread(machine1).start();
new Thread(machine2).start();
new Thread(machine3).start();
new Thread(machine4).start();
new Thread(machine5).start();
new Thread(gaogao).start();
new Thread(every).start();
}
}
/**
* 蛋糕实体
* @author 高伟
* @date Jan 6, 2012 1:43:01 PM
* @description:
*/
class Cake{
private int id;
public Cake(int id) {
this.id = id;
}
@Override
public String toString() {
return id+"";
}
}
/**
* 制作蛋糕机器
* @author 高伟
* @date Jan 6, 2012 1:43:43 PM
* @description:
*/
class Machine implements Runnable{
private String isbn;
private ConcurrentLinkedQueue<Cake> cakeList;
private static int count = 0;
public Machine(String isbn,ConcurrentLinkedQueue<Cake> cakeList) {
this.isbn = isbn;
this.cakeList = cakeList;
}
public void run(){
while(true){
synchronized (cakeList) {
Cake cake = new Cake(count++);
cakeList.add(cake);
System.out.printf("Machine (%s) create cake (%s).Total: (%s). Remain: (%s) \n", isbn, cake, count, cakeList.size());
cakeList.notify();
}
try {
//生产蛋糕需要消耗5秒的时间
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public String toString() {
return isbn;
}
}
/**
* 吃蛋糕
* @author 高伟
* @date Jan 6, 2012 1:49:36 PM
* @description:
*/
class Person implements Runnable{
private String name;
private ConcurrentLinkedQueue<Cake> cakeList;
public Person(String name,ConcurrentLinkedQueue<Cake> cakeList) {
this.name = name;
this.cakeList = cakeList;
}
public void run( ){
while(true){
synchronized (cakeList) {
if(cakeList.size()==0){
try {
cakeList.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Cake cake = cakeList.poll();
System.out.printf("Cake (%s) is eated by person (%s).\n" , cake, this);
}
try {
//吃掉蛋糕也需要1秒的时间
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public String toString() {
return name;
}
}