阻塞队列——BlockingQueue&Consumer和Productor问题

试用一下BlockingQueue:

简单的生产者与消费者问题: 一个消费者,两个生产者

package com.concurrency.dataStucture;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueTest<E> {
	/**
	 * 阻塞队列的应用举例
	 * 生产者-消费者问题可以使用该数据类型来进行解决
	 */
	public BlockingQueue<E> datas = null;   //the cache area
	public BlockingQueueTest(BlockingQueue<E> datas){
		this.datas = datas;
	}
	public static int consumeCounter = 0;
	public static int productCounter = 0;  //the counter

	public synchronized int getConsumerCounter(){
		return consumeCounter;
	}
//	public synchronized int getProductCounter(){
//		return productCounter;
//	}
//	public synchronized void writeProductCounter(){
//		productCounter++;
//	}
	public void run(){  //function 
		Consumer<E> c = new Consumer<E>(datas);
		Productor<E> p1 = new Productor<E>(datas);
		Productor<E> p2 = new Productor<E>(datas);
		Thread t1 = new Thread(c, "ct");
		Thread t2 = new Thread(p1, "pt:1");
		Thread t3 = new Thread(p2, "pt:2");
		t1.start();
		t2.start();
		t3.start();
	}
	class Consumer<E> implements Runnable{   //consumer
		private final BlockingQueue<E> cache;
//		public static int counter=0;
		public Consumer(BlockingQueue<E> cache){
			this.cache = cache;   //cache area
		}
		@Override
		public void run() {  //every consumer consume 20 elements;
			// TODO Auto-generated method stub
			for(int i =0;i<10;i++){
				try{
					consume();   //consume
					
				}catch(InterruptedException e){
					System.out.println(Thread.currentThread().getName()+":"+e.getMessage());
				}
			}
		}
		public synchronized void consume() throws InterruptedException{
			E elem =cache.take();  // take the product to consume
			consumeCounter++;
			System.out.println("consume : the Num is"+getConsumerCounter()+"---------"+(String)elem);
		}
		
	}
	class Productor<E> implements Runnable{  //productor
		private final BlockingQueue<E> cache;
		public Productor(BlockingQueue<E> cache){
			this.cache = cache;   //cache area
		}
		@SuppressWarnings("unchecked")
		@Override
		public void run() {
			// TODO Auto-generated method stub
			for(int i=0;i<5;i++){ // every productor product 20 elements
				try{
					product(i);
				}catch(Exception e){
					System.out.println(Thread.currentThread().getName()+":"+e.getMessage());

				}
			}	
		}
		public void product(int i) throws InterruptedException{
			E elme =  (E) new String(Thread.currentThread().getName()+"+p:"+i);
//			writeProductCounter();
			cache.put(elme);
			System.out.println("product : "+"---------"+(String)elme);
		}
		
	}
	public static void main(String[] args){
		BlockingQueue<String> cache = new ArrayBlockingQueue<String>(20);  //capacity = 20
		BlockingQueueTest<String> bqt = new BlockingQueueTest<String>(cache);
		bqt.run();
	}

}



这里给个有特点的结果:

product : ---------pt:2+p:0
consume : the Num is1---------pt:1+p:0
product : ---------pt:1+p:0
consume : the Num is2---------pt:2+p:0
product : ---------pt:2+p:1
consume : the Num is3---------pt:2+p:1
product : ---------pt:1+p:1
consume : the Num is4---------pt:1+p:1
product : ---------pt:2+p:2
consume : the Num is5---------pt:2+p:2
product : ---------pt:1+p:2
consume : the Num is6---------pt:1+p:2
product : ---------pt:2+p:3
consume : the Num is7---------pt:2+p:3
product : ---------pt:1+p:3
consume : the Num is8---------pt:1+p:3
product : ---------pt:2+p:4
consume : the Num is9---------pt:2+p:4
product : ---------pt:1+p:4
consume : the Num is10---------pt:1+p:4

看结果里面的问题:

打印的第一个产品是product  2-0, 但是消费的是 1-0,  (Thread-i);

不要以为这里程序出问题了,这里其实没出问题,只是打印的慢了点,原因是这样的:

当product 的线程pt1执行 到cache.add(elme)的时候,cpu 切换到执行 consumer线程,然后 consumer执行完之后,又切换回pt1  接着执行 syso语句,所以这里出现这个打印顺序;

因此 ,如果在实际问题中, 需要处理的问题要 一气呵成(就是不会出现上面那种现象),可以通过synch关键字或者锁进行有效的控制。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值