经典的生产者与消费者模型(基于BlockingQueue队列实现)

基于BlockingQueue实现与之前的基于synchronized方法实现的不同,这里不需要单独创建仓库类,用队列替代仓库,简化编程。

BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种:

1. 当队列满了的时候进行入队列操作
2. 当队列空了的时候进行出队列操作

负责生产的线程不断的制造新对象并插入到阻塞队列中,直到达到这个队列的上限值。队列达到上限值之后生产线程将会被阻塞,直到消费的线程对这个队列进行消费。同理,负责消费的线程不断的从队列中消费对象,直到这个队列为空,当队列为空时,消费线程将会被阻塞,除非队列中有新的对象被插入。

实现代码如下:

package queue.producer.consumer;

import java.util.concurrent.*;

/**
 * 生产者与消费者
 * @author tiger
 * @Date 2017年7月27日
 */
public class ProducerAndConsumerQueue {
	public static void main(String[] args) throws InterruptedException {
		//替代仓库类
		BlockingQueue
   
   
    
     queue  = new ArrayBlockingQueue
    
    
     
     (20);
		
		Producer pro1 = new Producer(queue);
		Producer pro2 = new Producer(queue);
		Salesman con = new Salesman(queue);
		
		Thread make1 = new Thread(pro1,"1号生产机器");//生产者线程 1 号
		Thread make2 = new Thread(pro2,"2号生产机器");//生产者线程 2 号
		
		Thread cons1 = new Thread(con,"老鼠销售员1");//销售员线程1
		Thread cons2 = new Thread(con,"老虎销售员2");//销售员线程2
		Thread cons3 = new Thread(con,"蓝猫销售员3");//销售员线程3
		Thread cons4 = new Thread(con,"兔子销售员4");//销售员线程4
		Thread cons5 = new Thread(con,"小红销售员5");//销售员线程5
		
		make1.start();
		make2.start();
		cons1.start();
		cons2.start();
		cons3.start();
		cons4.start();
		cons5.start();
	}
}
    
    
   
   

   
   
    
    
     
     package queue.producer.consumer;

import java.util.concurrent.*;
/**
 * 生产者
 * @author tiger
 * @Date 2017年7月28日
 */
class Producer implements Runnable{
	//持有队列,类似于仓库
	final BlockingQueue
     
     
      
       queue ;
	
	public Producer(BlockingQueue
      
      
       
        queue) {
		this.queue = queue;
	}
	public void productGoods(){
		//货物ID
		int ran = (int) (Math.random()*1000);
		//生产者名称
		String name = Thread.currentThread().getName();
		String id = String.valueOf(ran);
		try {
			queue.put(id);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//生产货物
		System.out.println(name+" 生产一个货物["+id+"],现在货物数量" + queue.size());
	}
	@Override
	public void run() {
		//仓库只要没有满就一直不停在生产货物
		while (true) {
			productGoods();
			//模拟每个货物生产需要花费的时间
			try {
				TimeUnit.MICROSECONDS.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
      
      
     
     
    
    
   
   

   
   
    
    
     
     
      
      
       
       package queue.producer.consumer;

import java.util.concurrent.*;
/**
 * 销售员
 * @author tiger
 * @Date 2017年7月27日
 */
class Salesman implements Runnable{
	//代替了面包店
	final BlockingQueue
       
       
         queue ; public Salesman(BlockingQueue 
        
          queue) { this.queue = queue; } public void sellGoods(){ String name = Thread.currentThread().getName(); try { String id = queue.take(); System.out.println(name+" 卖掉一个货物["+id+"],现在货物数量" + queue.size()); System.out.println("------------------------------"); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public void run() { //仓库只要有货物就一直不停卖 while (true) { sellGoods(); //模拟卖一个货物所需要花费的时间 try { TimeUnit.MICROSECONDS.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } } } 
         
       
      
      
     
     
    
    
   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ljt-tiger

thanks

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值