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

试用一下BlockingQueue:

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

package com.concurrency.dataStucture;

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

public class BlockingQueueTest {
	/**
	 * 阻塞队列的应用举例
	 * 生产者-消费者问题可以使用该数据类型来进行解决
	 */
	public BlockingQueue datas = null;   //the cache area
	public BlockingQueueTest(BlockingQueue 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 c = new Consumer(datas);
		Productor p1 = new Productor(datas);
		Productor p2 = new Productor(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 implements Runnable{   //consumer
		private final BlockingQueue cache;
//		public static int counter=0;
		public Consumer(BlockingQueue 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 implements Runnable{  //productor
		private final BlockingQueue cache;
		public Productor(BlockingQueue 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 cache = new ArrayBlockingQueue(20);  //capacity = 20
		BlockingQueueTest bqt = new BlockingQueueTest(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关键字或者锁进行有效的控制。

你可能感兴趣的:(工作之前的随笔,BlockingQueue,Java,thread,并发,生产者和消费者)