Java编写生产者消费者问题

生产者消费者问题


问题描述

生产者(Producer)将产品交给店员(Clerk),而消费者(Consumer)从店员处取走产品, 店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。

分析

  1. 是否是一个多线程问题?
    是,至少存在两个线程,一个是生产者(Producer),一个是消费者(Consumer)
  2. 是否存在线程安全问题?
    是,问题中存在着共享数据,即产品(Product)数量和店员(Clerk)
  3. 如何解决线程安全问题?
    使用同步机制,即 synchronized(同步代码块/同步方法)或 ReetrantLock 锁进行线程同步
  4. 是否存在线程通信以及如何进行线程通信?
    存在线程通信,两个线程同时操作共享数据。可以使用 wait() 方法和 notify() / notifyAll() 方法进行线程通信
代码实现

class Clerk{
	//这里为了简便,不再对产品进行建类,只用 productNum 整型变量表示产品数量
	private int productNum = 0; 
	public synchronized voido produceProduct(){
		if(productNum < 20){
			productNum ++;
			System.out.println(Thread.currentThread().getName() + "开始生产第" + productNum + "个产品");
			notify();	//每生产一件产品后就可以唤醒被wait的消费者线程进行消费
		}else{
			try{
				wait();	//当产品数量达到20件时,调用wait()阻塞当前线程,释放同步监视器
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
	}
	public synchronized void consumeProduct(){
		if(productNum > 0){
			System.out.println(Thread.currentThread().getName() + "开始消费第" + productNum + "个产品");
			productNum --;
			notify();	//每消费一件产品后就可以唤醒被wait的生产者线程进行生产
		}else{
			try{
				wait();	//当产品数量达到0件时,调用wait()阻塞当前线程,释放同步监视器
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
	}
}

class Producer implements Runnable{
	private Clerk clerk;
	public Producer(Clerk clerk){
		this.clerk = clerk;
	}
	@Override
	public void run(){
		System.out.println(Thread.currentThread().getName() + "开始生产产品...");
		while(true){
			try{
				Thread.sleep(10);
				clerk.produceProduct();
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
	}
}

class Consumer implements Runnable{
	private Clerk clerk;
	public Consumer(Clerk clerk){
		this.clerk = clerk;
	}
	@Override
	public void run(){
		System.out.println(Thread.currentThread().getName() + "开始消费产品...");
		while(true){
			try{
				Thread.sleep(10);
				clerk.consumeProduct();
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
	}
}

class ProductTest{
	public static void main(String[] args){
		Clerk clerk = new Clerk();
		
		Producer p = new Producer(clerk);
		Consumer c = new Consumer(clerk);
		
		Thread t1 = new Thread(p);	//创建生产者线程t1
		Thread t2 = new Thread(c);	//创建消费者线程t2
		
		t1.setName("生产者");
		t2.setName("消费者");

		t1.start();
		t2.start();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值