生产者消费者模式的一种java实现

今天试着用java写了下生产者消费者模式,还发现了一些有趣的问题,这里记录一下。

首先说一下大概思想,其实是参照了csdn上别的同学的代码,建立一个仓库类,其中保存着一个队列(linkedList实现)和向队列中添加货物和移去货物的操作,这些操作中对队列加锁以处理并发问题,再建立数个生产者线程和消费者线程来调用这些操作。

以下是代码(请无视各种奇怪的拼写。。):

仓库类

<pre name="code" class="java">class storage{
		LinkedList<Integer> list=new LinkedList<Integer>();
		int max=50;
		int min=20;
		void add(){
			synchronized (list) {
				//注意这里采用if判定
				if(list.size()>=max){
					System.out.println("storage too much");
					try{
						list.wait();
					}catch(InterruptedException e){
						e.printStackTrace();
					}
					//step
				}
				//必须再判定一次,因为if 只判定一次,在后面使用notifyAll()之后,程序从step
				//处开始,不经判定可导致生产量超出上限
				if(list.size()<max)list.add(1);	
				System.out.println("already has"+list.size());
				list.notifyAll();
				
			}
		}
		void consum(){
			synchronized (list) {
				//采用while
				while(list.size()<=min){
					System.out.println("storage not enough");
					try{
						list.wait();
					}catch(InterruptedException e){
						e.printStackTrace();
					}	
				}
				list.remove();
				System.out.println("cosum already has"+list.size());
				list.notifyAll();
				
			}
			
		}
	}


 生产者线程: 

  <pre name="code" class="java">  class producer extends Thread{
    	storage s;
    	public producer(storage s) {
			// TODO Auto-generated constructor stub
    		this.s=s;
		}
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		produce();
    	}
    	void produce(){
    		while (true)
    		s.add();
    	}
    }

 消费者线程 

class cosumer extends Thread{
    	storage s;
    	public cosumer(storage s) {
			// TODO Auto-generated constructor stub
    		this.s=s;
    		
		}
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		consum();
    	}
    	void consum(){
    		while(true)
    		s.consum();
    	}
    	
    }

main函数测试:

 public static void main(String[] args) {
		storage s=new storage();
		
		for(int i=1;i<3;i++){
			producer p=new producer(s);
			p.start();
		}
		for(int i=1;i<8;i++){
			cosumer c=new cosumer(s);
			c.start();
		}
		
	}

运行后货物不停地被生存和消费,但总数不会大于max,不会小于min。

好玩之处在仓库类中,add()方法每次开始都要测试仓库存量是否大于max,如果大于则当前线程被阻塞。这里用的是if语句,而整个if语句一结束要再次测试一下库存才能进入下一步操作。原因是add()方法使用了notifyAll()方法来唤醒所有线程,而线程被唤醒后是从代码注释//step处开始执行,这个时候如果没有再测试一下的话,在仓库已满的情况下,仍会执行后面的代码,导致仓库中的存量大于max。而在consum方法中采用while语句来判定,线程回复后仍要在while模块内进行判断,就不会有这种异常出现啦!


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值