生产者与消费者问题是多线程中经典问题
生产者生产产品放入仓库,消费者从仓库中取出消费产品,仓库的容量有限
生产者和消费者都可以有多个
创建产品,仓库,生产者,消费者和main主线程五个类
产品类:
package ProducerAndConsumer;
//产品——面包类
public class Bread {
private String producer;
public Bread(String producer){
super();
this.producer = producer;
}
@Override
public String toString(){
return producer;
}
}
仓库类:
package ProducerAndConsumer;
//仓库——篮子类
public class Basket {
private int index = 0;
private Bread[] arrayBread = new Bread[10];
public synchronized void push(Bread bread){
System.out.println("生产前有面包"+index+"个");
if(index == arrayBread.length){
System.out.println("篮子满了");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
return;
}
this.notify();
arrayBread[index] = bread;
index++;
System.out.println(bread);
}
public synchronized Bread pop(int id){
System.out.println("消费前有面包"+index+"个");
while(index == 0){
System.out.println("篮子空了");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify();
index--;
System.out.println("第"+id+"个吃货吃了"+arrayBread[index]);
return arrayBread[index];
}
}
生产者类:
package ProducerAndConsumer;
//生产者——厨师
public class Kitchener implements Runnable {
private Basket basket;
private int id;
public Kitchener(int id, Basket basket){
super();
this.id = id;
this.basket = basket;
}
@Override
public void run() {
for(int i = 0; i < 10; i++){
Bread bread = new Bread("第"+id+"个厨师做的面包");
basket.push(bread);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
消费者类:
package ProducerAndConsumer;
//消费者——吃货
public class Consumer implements Runnable{
private Basket basket;
private int id;
public Consumer(int id, Basket basket){
super();
this.id = id;
this.basket = basket;
}
@Override
public void run() {
for(int i = 0; i < 10; i++){
basket.pop(id);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试类,主线程:
package ProducerAndConsumer;
public class TestProducerAndConsumer {
public static void main(String[] args) {
Basket basket = new Basket();
//两个厨师两个吃货
Kitchener k1 = new Kitchener(1, basket);
Kitchener k2 = new Kitchener(2, basket);
Consumer c1 = new Consumer(1, basket);
Consumer c2 = new Consumer(2, basket);
new Thread(k1).start();
new Thread(k2).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
其中一次的运行结果:
消费前有面包0个
篮子空了
生产前有面包0个
第1个厨师做的面包
消费前有面包1个
第2个吃货吃了第1个厨师做的面包
生产前有面包0个
第2个厨师做的面包
第1个吃货吃了第2个厨师做的面包
生产前有面包0个
第1个厨师做的面包
生产前有面包1个
第2个厨师做的面包
生产前有面包2个
第2个厨师做的面包
生产前有面包3个
第1个厨师做的面包
生产前有面包4个
第1个厨师做的面包
生产前有面包5个
第2个厨师做的面包
生产前有面包6个
第1个厨师做的面包
生产前有面包7个
第2个厨师做的面包
生产前有面包8个
第1个厨师做的面包
生产前有面包9个
第2个厨师做的面包
生产前有面包10个
篮子满了
生产前有面包10个
篮子满了
消费前有面包10个
第2个吃货吃了第2个厨师做的面包
消费前有面包9个
第1个吃货吃了第1个厨师做的面包
生产前有面包8个
第1个厨师做的面包
生产前有面包9个
第2个厨师做的面包
生产前有面包10个
篮子满了
生产前有面包10个
篮子满了
消费前有面包10个
第2个吃货吃了第2个厨师做的面包
消费前有面包9个
第1个吃货吃了第1个厨师做的面包
生产前有面包8个
第1个厨师做的面包
生产前有面包9个
第2个厨师做的面包
消费前有面包10个
第1个吃货吃了第2个厨师做的面包
消费前有面包9个
第2个吃货吃了第1个厨师做的面包
消费前有面包8个
第2个吃货吃了第2个厨师做的面包
消费前有面包7个
第1个吃货吃了第1个厨师做的面包
消费前有面包6个
第1个吃货吃了第2个厨师做的面包
消费前有面包5个
第2个吃货吃了第1个厨师做的面包
消费前有面包4个
第1个吃货吃了第1个厨师做的面包
消费前有面包3个
第2个吃货吃了第2个厨师做的面包
消费前有面包2个
第1个吃货吃了第2个厨师做的面包
消费前有面包1个
第2个吃货吃了第1个厨师做的面包
消费前有面包0个
篮子空了
消费前有面包0个
篮子空了