问题描述:生产者将产品交给店员,而消费者从店员处取走产品。店员一次只能持有固定数量的产品,如果生产过多的产品,店员会要求生产者等一下,如果店中没有产品,店员会要求消费者等一下。这样会出现两个问题:
1、生产者比消费者快时,消费者会漏掉一些数据没有取到。
2、消费者比生产者快时,消费者会取相同的数据。
因而针对这些特殊情况,需要生产者线程和消费者线程保持同步,防止操作到的共享数据出错。
代码说明:
class Clerk{//店员
private int product = 0;//默认0个产品
//生产者将生产的产品交给店员
public synchronized void addProduct(){
if(this.product >= 20){
try {
wait();//产品已满,请生产者稍后在生产
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
product++;
System.out.println("生产者生产第" + product + "个产品");
notifyAll();//通知等待区的消费者可以取产品
}
}
//消费者从店员这获取产品
public synchronized void getProduct(){
if(this.product <= 0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("消费者从店员处取出第" + product +"个产品");
product--;
notifyAll();//通知等待区的生产者可以生产产品
}
}
}
class Producer implements Runnable{
Clerk clerk;
public Producer(Clerk clerk){
this.clerk = clerk;
}
@Override
public void run() {
System.out.println("生产者开始生产产品");
try {
Thread.sleep((int)(Math.random()*10)*10);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.addProduct();//生产产品
}
}
class Consumer implements Runnable{
Clerk clerk;
public Consumer(Clerk clerk){
this.clerk = clerk;
}
@Override
public void run() {
System.out.println("消费者开始取出产品");
try {
Thread.sleep((int)(Math.random()*10)*100);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.getProduct();//取产品
}
}
public class ProducerConsumerTest {
public static void main(String[] args){
Clerk clerk = new Clerk();
Thread producerThread = new Thread(new Producer(clerk));//生产者线程
Thread consumerThread = new Thread(new Consumer(clerk));//消费者线程
producerThread.start();
consumerThread.start();
for(int i = 0; i < 10; i++){
Thread th = new Thread(new Producer(clerk));
th.start();
}
for(int i = 0; i < 10; i++){
Thread th = new Thread(new Consumer(clerk));
th.start();
}
}
}
参考对比:http://blog.csdn.net/shengwusuoxi/article/details/22725285
该博文是用栈才存储产品数据