简单的多生产多消费模式代码

资源描述类:

/**
 * 资源描述类
 * @author gaojh
 *
 */
public class Product {
	
	List<String> product = null;

	public Product() {
		super();
		this.product = new ArrayList<>();
	} 

	/**
	 * 生产方法
	 * @author: gaojh
	 * @throws InterruptedException 
	 * @date: 2018年4月16日 下午3:53:29
	 */
	public synchronized void produce() throws InterruptedException{
		if(product != null && product.size() < 1000){ //仅在产品List不为null且长度小于10时进行生产
			String singleProduct =  Thread.currentThread().getName() + "的产品";
			product.add(singleProduct);
			System.out.println(Thread.currentThread().getName()+"生产了"+singleProduct);
		}else{
			System.out.println(Thread.currentThread().getName()+"开始唤醒了");
			this.notifyAll();
			System.out.println(Thread.currentThread().getName()+"进入wait了");
			this.wait();
		}
	}
	
	
	/**
	 * 消费方法
	 * @author: gaojh
	 * @throws InterruptedException 
	 * @date: 2018年4月16日 下午3:53:29
	 */
	public synchronized void consume() throws InterruptedException{
		
		if(product != null && product.size() > 0){ //仅在产品List不为null且长度大于0时进行消费
			String singleProduct =  product.remove(0); //消费第一个
			System.out.println(Thread.currentThread().getName()+"消费了"+singleProduct);
		}else{
			System.out.println(Thread.currentThread().getName()+"开始唤醒了");
			this.notifyAll();
			System.out.println(Thread.currentThread().getName()+"进入wait了");
			this.wait();
		}
		
	}
	
}

生产者:

/**
 * 生产者类
 * @author gaojh
 *
 */
public class Producer implements Runnable{
	
	Product product = null;
	
	public Producer(Product product) {
		super();
		this.product = product;
	}
	
	@Override
	public void run() {
		//生产逻辑
		try {
			while(true){
				product.produce();
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

消费者:

/**
 * 消费者类
 * @author gaojh
 *
 */
public class Consumer implements Runnable{
	
	Product product = null;
	
	public Consumer(Product product) {
		super();
		this.product = product;
	}

	@Override
	public void run() {
		//消费逻辑
		try {
			while(true){
				product.consume();
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

Main方法类:

/**
 * 测试多生产多消费
 * @author gaojh
 *
 */
public class TestThread {
	
	public static void main(String[] args) {
		Product product = new Product(); //创建唯一资源
		
		//生产者
		Producer producer = new Producer(product);
		
		Thread producer1 = new Thread(producer); //生产者1
		producer1.setName("生产者1");
		Thread producer2 = new Thread(producer); //生产者2
		producer2.setName("生产者2");
		Thread producer3 = new Thread(producer); //生产者3
		producer3.setName("生产者3");
		
		producer1.start();
		producer2.start();
		producer3.start();
		
		//消费者
		Consumer consumer = new Consumer(product);
		
		Thread consumer1 = new Thread(consumer); //消费者1
		consumer1.setName("消费者1");
		Thread consumer2 = new Thread(consumer); //消费者2
		consumer2.setName("消费者2");
		Thread consumer3 = new Thread(consumer); //消费者3
		consumer3.setName("消费者3");
		consumer1.start();
		consumer2.start();
		consumer3.start();
		
	}
}


问:为什么在notifyAll之后让当前线程wait?

答:当前线程既然已经执行到notifyAll了,说明当前线程该做的及该类型线程该做的都已经完成了,如果下次竞争syn的锁,当前线程再次竞争持有(很有可能),只是进来唤醒了其他线程而已,没有必要,wait至少可以让当前线程释放锁,等待被唤醒。这样竞争线程从6个变为5个,无论是生产者还是消费者进入等待,对方线程只有syn锁的数字几率都会变大。


PS:现在在产品满了/空了后,无法指定唤醒消费者/生产者,只能全部唤起然后一个一个判断。效率上不行,要想办法修改。

阅读更多
个人分类: java底层 杂七杂八
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭