使用Lock和Condition实现生产者消费者模型

package Condition;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 仓库类Storage实现缓冲区
 * @author Tao
 *
 */
class Storage {
	
	//仓库最大存储量
	private int MAX_SIZE;
	//仓库存储的载体
	private LinkedList<Object> list = new LinkedList<>();
	//锁
	private final Lock lock = new ReentrantLock();
	//“仓库满”的条件变量
	private final Condition produceCondition = lock.newCondition();
	//“仓库空”的条件变量
	private final Condition consumeCondition = lock.newCondition();
	
	public Storage(int maxSize) {
		this.MAX_SIZE = maxSize;
	}
	
	/**
	 * 生产num个产品
	 * @param num
	 */
	public void produce(int num) {
		
		//获取锁
		lock.lock();
		
		//剩余空位置不足
		while(list.size() + num >= MAX_SIZE) {
			
			System.out.println("【要生产的产品数量】:" + num + "\t【库存量】:" + list.size()  
             + "\t【剩余空间】:" + (MAX_SIZE - list.size()) + "\t暂时不能执行生产任务!"); 
			
			try {
				//没法生产,先阻塞
				produceCondition.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		//剩余空间足够,生产num个产品
		for(int i = 0; i < num; ++i) {
			list.addLast(new Object());
		}
		System.out.println("【本次生产产品数】:" + num + "\t【当前库存为】:" + list.size()); 
		
		//唤醒所有消费者线程
		consumeCondition.signalAll();
		//解锁
		lock.unlock();
	}
	
	/**
	 * 消费num个产品
	 * @param num
	 */
	public void consume(int num) {
		
		//获得锁
		lock.lock();
		
		//如果仓库存储量不够num个,本次消费阻塞
		while(list.size() < num) {
			
			System.out.println("【要消费的产品数量】:" + num + "\t【库存量】:" + list.size()  
            + "\t暂时不能执行消费任务!");  
			
			try {
				//没法消费,阻塞
				consumeCondition.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		//库存足够本次消费,消费num个产品
		for(int i = 0; i < num; ++i) {
			list.removeFirst();
		}
		System.out.println("【本次消费产品数】:" + num + "\t【当前库存为】:" + list.size());
		
		//消费完了,唤醒所有生产者线程
		produceCondition.signalAll();
		//释放锁
		lock.unlock();
	}
		
}


/**
 * 生产者类
 * 一个生产者对应一个线程
 * @author Tao
 *
 */
class Producer extends Thread {
	
	//每次生产的数量
	private int num;
	//持有的仓库的引用
	private Storage storage;
	
	public Producer(int num, Storage storage) {
		this.num = num;
		this.storage = storage;
	}
	
	@Override
	public void run() {
		try {
			while(true) {
				//生产产品
				storage.produce(num);
				Thread.sleep(3000);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}


/**
 * 消费者类
 * 一个消费者对应一个线程
 * @author Tao
 *
 */
class Consumer extends Thread {
	
	//每次消费的数量
	private int num;
	//仓库的引用
	private Storage storage;
	
	public Consumer(int num, Storage storage) {
		this.num = num;
		this.storage = storage;
	}
	
	@Override
	public void run() {
		try {
			while(true) {
				storage.consume(num);
				Thread.sleep(4000);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
}



public class Test {
	
	public static void main(String[] args) {
		
		Storage storage = new Storage(100);
		
		//生产者 
		Producer[] producers = new Producer[7];
		for(int i = 0; i < producers.length; ++i) {
			producers[i] = new Producer(40, storage);
		}
		
		//消费者
		Consumer[] consumers = new Consumer[14];
		for(int i = 0; i < consumers.length; ++i) {
			consumers[i] = new Consumer(26, storage);
		}
		
		for (Producer producer : producers) {
			producer.start();
		}
		for (Consumer consumer : consumers) {
			consumer.start();
		}
		
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值