1. 程式人生 > >java使用阻塞佇列實現生產者消費者模式

java使用阻塞佇列實現生產者消費者模式

Java 5之前實現同步存取時,可以使用普通的一個集合,然後在使用執行緒的協作和執行緒同步可以實現生產者,消費者模式,主要的技術就是用好,wait ,notify,notifyAll,sychronized這些關鍵字。而在java 5之後,可以使用組阻塞佇列來實現,此方式大大簡少了程式碼量,使得多執行緒程式設計更加容易,安全方面也有保障。

BlockingQueue介面是Queue的子介面,它的主要用途並不是作為容器,而是作為執行緒同步的的工具,因此他具有一個很明顯的特性,當生產者執行緒試圖向BlockingQueue放入元素時,如果佇列已滿,則執行緒被阻塞,當消費者執行緒試圖從中取出一個元素時,如果佇列為空,則該執行緒會被阻塞,正是因為它所具有這個特性,所以在程式中多個執行緒交替向BlockingQueue中放入元素,取出元素,它可以很好的控制執行緒之間的通訊。

package com.queue;

import java.util.concurrent.BlockingQueue;

/***
 * 消費者
 * **/
public class Consumer extends Thread {
	/***
	 * 利用佇列儲存樣品
	 * */
	 private BlockingQueue<String> bq;
	 public Consumer() {
		// TODO Auto-generated constructor stub
	}
	public Consumer(BlockingQueue<String> bq) {
		super();
		this.bq = bq;
	 
	}
	 
	
	@Override
	public void run() {
		
		while(true){
			System.out.println(getName()+"消費者準備消費集合元素");
			try{
				
				Thread.sleep(2000);
				//嘗試取出元素,如果佇列為空,則被執行緒阻塞
				bq.take();
				
			}catch(Exception e){
				e.printStackTrace();
			}
			
			System.out.println(getName()+"消費完成"+bq);
		}
		
	}
	 

	
	 
	
	  
	
	
}

 生成者
package com.queue;

import java.util.concurrent.BlockingQueue;

/**
 * 生產者
 * **/
public class Producer  extends Thread{

	/***
	 * 利用佇列儲存樣品
	 * */
	private BlockingQueue<String> bq;
	
	public Producer() {
		// TODO Auto-generated constructor stub
	}
	 
	public Producer(BlockingQueue<String> bq) {
	 
		this.bq = bq;
	}

	@Override
	public void run() {
		String []str=new String[]{"solr","lucene","nutch"}; 
		
		for(int i=0;i<99999999;i++){
			System.out.println(getName()+"生產者準備生產集合元素了!");
			try{
				Thread.sleep(2000);
				//嘗試放入元素,如果對列已滿,則執行緒被阻塞
				bq.put(str[i%3]);
				
			}catch(Exception e){
				e.printStackTrace();
			}
			System.out.println(getName()+"生產完成:"+bq);
		}
		
		
	}
	
	
}