不管任何语言,生产消费者模型都是最经典的,就像每一门编程语言“Hello World!”一样。
准确来说,应该是“生产-消费-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。
业务描述如下:
(1)、生产者在仓库未满时进行生产,仓库满了,则停止生产。
(2)、消费者仅仅在仓库有产品时才能进行消费,空仓则进行等待。
(3)、当消费者发现仓库没有产品可以消费时,就通知生产者进行生产。
(4)、生产者在生产出产品以后,应该通知等待的消费者进行消费。
代码如下:
package Test;
public class Main {
public static void main(String args[]){
GoDown goDown=new GoDown(30);
Consumer consumer1=new Consumer(50,goDown);
Consumer consumer2=new Consumer(20,goDown);
Consumer consumer3=new Consumer(30,goDown);
Producer producer1=new Producer(10,goDown);
Producer producer2=new Producer(10,goDown);
Producer producer3=new Producer(10,goDown);
Producer producer4=new Producer(10,goDown);
Producer producer5=new Producer(10,goDown);
Producer producer6=new Producer(10,goDown);
Producer producer7=new Producer(80,goDown);
consumer1.start();
consumer2.start();
consumer3.start();
producer1.start();
producer2.start();
producer3.start();
producer4.start();
producer5.start();
producer6.start();
producer7.start();
}
}
/**
* 仓库
*/
class GoDown {
public static final int max_size=100;//库存量
public int curNum;//当前库存量
GoDown(){
}
GoDown(int curNum){
this.curNum=curNum;
}
/**
* 生产指定数量的产品
* @param needNum
*/
public synchronized void produce(int needNum){
//测试是否需要生产
while ((this.curNum+needNum)>max_size){
System.out.println("要生产的产品数量:"+needNum+",超过剩余库存量:"+(max_size-this.curNum)+",暂时不能执行生产任务");
try {
//当前的生产者等待
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//满足条件则进行生产,并更改当前库存量
this.curNum+=needNum;
System.out.println("已经生产了"+needNum+"个产品,现库存量为:"+this.curNum);
//唤醒在此监视器上等待的所有的线程
notifyAll();
}
/**
* 消费指定数量的产品
* @param needNum
*/
public synchronized void consume(int needNum){
//测试是否可以消费
while (this.curNum<needNum){
try {
//当前的生产线程等待
wait();
}catch (Exception e){
e.printStackTrace();
}
}
//满足条件则进行消费
this.curNum-=needNum;
System.out.println("已经消费了"+needNum+"个产品,现库存量为:"+this.curNum);
//唤醒在此对象监视器上等待的所有的线程
notifyAll();
}
}
/**
* 生产者
*/
class Producer extends Thread {
private int needNum;//生产产品的数量
private GoDown goDown;//库存
Producer(int needNum,GoDown goDown){
this.needNum=needNum;
this.goDown=goDown;
}
/**
* 生产指定数量的产品
*/
@Override
public void run() {
goDown.produce(this.needNum);
}
}
/**
* 消费者
*/
class Consumer extends Thread {
private int needNum;//消费产品的数量
private GoDown goDown;//库存
Consumer(int needNum,GoDown goDown){
this.needNum=needNum;
this.goDown=goDown;
}
/**
* 消费指定数量的产品
*/
@Override
public void run() {
goDown.consume(this.needNum);
}
}
运行结果如下:
已经消费了20个产品,现库存量为:10
已经生产了10个产品,现库存量为:20
已经生产了10个产品,现库存量为:30
已经生产了10个产品,现库存量为:40
已经消费了30个产品,现库存量为:10
已经生产了10个产品,现库存量为:20
已经生产了10个产品,现库存量为:30
已经生产了10个产品,现库存量为:40
要生产的产品数量:80,超过剩余库存量:60,暂时不能执行生产任务
说明:
当不能满足生产者和消费者的条件的时候,调用对象的wait方法,wait方法时释放当前线程所获得的锁,并调用对象的notifyAll()方法,通知该对象上的其它线程,使得其它线程继续执行,使得整个生产者和消费者得以运行。
notifyAll方法起到的是一个通知作用,不释放锁,也不获取锁,只告诉该对象等待的线程“可以竞争执行了”。