java concurrent下BlockQueue阻塞队列应用

最近在公司做大批量的数据交换用到了阻塞队列(mysql->mongodb,约600w左右的数据,期间包含了其他业务逻辑,不纯是数据交换),效率蛮不错。现在写个queue使用例子,供其他人参考。如有不对之处,欢迎指导...小弟第一次发技术贴

 

 

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * 
 * @Title: MyQueue.java
 * @Copyright: Copyright (c) 2005
 * @Description: <br> <br>
 * @Company:*
 * @Created on Jun 15, 2012 10:19:01 AM
 * @author <a href="mailTo:*">tzb</a>
 */
public class MyQueue extends ArrayBlockingQueue<Object>{

	private static final long serialVersionUID = 1L;

	/**
	 * 构造一个队列
	 * @param size
	 */
	public MyQueue(int size){
		super(size);
	}
	
	/**
	 * 定义一个Puter
	 */
	class Puter implements Callable<Object>{

		private MyQueue queue;

		public Puter(MyQueue queue){
			this.queue=queue;
		}

		public Object call() {
			try {
				for (int i = 0; i < 5; i++) {
					queue.put(i);
					System.out.println(Thread.currentThread().getName()+" put data :"+i);
					Thread.sleep(1 * 2000);
				}
				//结束时将标志放入队列,防止队列中没有数据后消费者一直阻塞等待,从而告知消费者可以退出
				queue.put(endDataFlag);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return "put data over...";
		}
	}
	
	/**
	 * 定义一个结束标示
	 */
	private static Object endDataFlag=new Object();

	/**
	 * 
	 * 定义一个Taker
	 */
	class Taker  implements Callable<Object>{
		private MyQueue queue;

		public Taker(MyQueue queue){
			this.queue=queue;
		}

		public Object call() {
			boolean flag=true;
			while (flag) {
				try {
					Object data=queue.take();
					//每次获取数据后判断获取的数据是否是最后一个结束标示,如果是并且队列已经为空,则退出消费
					if (data == endDataFlag && queue.isEmpty()) {
					   //此处重新将结束标示放入队列,防止其他消费者上次任务消费完毕后,下次去队列中取不到数据而导致阻塞
						queue.put(data);
						flag=false;
					}else{
						System.out.println(Thread.currentThread().getName()+" take data :"+data);
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			return "take data over...";
		}
	}

	public static void main(String[] args) throws Exception {
	    
		MyQueue que=new MyQueue(5);
		
	    ExecutorService exs=Executors.newCachedThreadPool();
	    
	    List<Callable<Object>> tasks=new ArrayList<Callable<Object>>();
	 
	    tasks.add(que.new Puter(que));
	    
	    tasks.add(que.new Taker(que));
	    
	    List<Future<Object>> listResult=exs.invokeAll(tasks);//提交执行所有task
	    
	    for(Future<Object> f:listResult){
	        System.out.println(Thread.currentThread().getName()+":"+f.get());//获取结果
	    }
	    exs.shutdown();
	    System.out.println("task over...");
	}

}

你可能感兴趣的:(java concurrent下BlockQueue阻塞队列应用)