import java.lang.Thread;
import java.lang.Runnable;
/**
* @function :
* M个生产者,N个消费者=多个线程
* 需要一个容器来放置生产的物品=共享区域
* synchronized同步非静态方法时,是对该类的实例(对象)加锁.
* 同一时刻该对象内只能有一个synchronized方法执行
* 一般我们都使用notifyAll,唤醒所有阻塞在该对象上的线程
* notify只是随机唤醒一个线程
* @author :Eric He
* @company :fdu
* @date :2009-12-9
*/
public class TestSyn {
public static void main(String[] args){
//生成一个产品的容器
Container c = new Container(5);
//生成3个生产者,分别准备生产4,8,6个产品
new Thread( new Producer(c,1, 4)).start();
new Thread( new Producer(c,2, 5)).start();
new Thread( new Producer(c,3, 3)).start();
//生成2个消费者,每次均消费一个产品
new Thread( new Consumer(c,1)).start();
new Thread( new Consumer(c,2)).start();
}
}
class Container{
private int currentSize;
private Product[] pros;
Container(int counts){
assert(counts>0);
this.pros = new Product[counts];
currentSize = 0;
}
public synchronized void put(Product p){
//使用while,不能用if,因为在被唤醒后仍需要检查容器是否已满
while(currentSize == pros.length ){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
pros[currentSize++]=p;
}
public synchronized Product get(){
while(currentSize == 0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
return pros[--currentSize];
}
}
class Producer implements Runnable{
private Container c;
//预生产产品的数量
private int preCounts;
//生产者id
private int producerID;
Producer(Container c ,int producerID, int preCounts){
this.c = c;
this.preCounts = preCounts;
this.producerID = producerID;
}
public void run(){
for(int i= 0; i<preCounts; i++){
Product p =new Product(i);
c.put(p);
System.out.println("生成者"+producerID+"生产 "+p);
try {
Thread.sleep((long)Math.random()*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable{
private Container c;
private int consumerID;
Consumer(Container c, int consumerID){
this.c = c;
this.consumerID = consumerID;
}
public void run(){
while(true){
Product p = c.get();
System.out.println("消费者"+consumerID+"消费 "+p);
}
}
}
class Product{
private int proID;
Product(int i){
proID = i;
}
public String toString(){
return "[Product"+proID+"]";
}
}