java使用阻塞佇列實現生產者消費者模式
阿新 • • 發佈:2019-01-29
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); } } }