线程同步经典问题——生产者消费者问题

问题描述:生产者将产品交给店员,而消费者从店员处取走产品。店员一次只能持有固定数量的产品,如果生产过多的产品,店员会要求生产者等一下,如果店中没有产品,店员会要求消费者等一下。这样会出现两个问题:

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

该博文是用才存储产品数据

你可能感兴趣的:(java,线程)