併發包中的BlockingQueue這個類的介紹及使用
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
本例介紹一個特殊的佇列:BlockingQueue,如果BlockQueue是空的,從BlockingQueue取東西的操作將會被阻斷進入等待狀態,直到BlockingQueue進了東西才會被喚醒.同樣,如果BlockingQueue是滿的,
本例再次實現11.4執行緒----條件Condition中介紹的籃子程式,不過這個籃子中最多能放的蘋果數不是1,可以隨意指定.當籃子滿時,生產者進入等待狀態,當籃子空時,消費者等待.
*/
/**
使用BlockingQueue的關鍵技術點如下:
1.BlockingQueue定義的常用方法如下:
1)add(anObject):把anObject加到BlockingQueue裡,即如果BlockingQueue可以容納,則返回true,否則招聘異常
2)offer(anObject):表示如果可能的話
3)put(anObject):把anObject加到BlockingQueue裡,如果BlockQueue沒有空間,則呼叫此方法的執行緒被阻斷直到BlockingQueue裡面有空間再繼續.
4)poll(time):取走BlockingQueue裡排在首位的物件,若不能立即取出,則可以等time引數規定的時間,取不到時返回null
5)take():取走BlockingQueue裡排在首位的物件,若BlockingQueue為空,阻斷進入等待狀態直到Blocking
2.BlockingQueue有四個具體的實現類,根據不同需求,選擇不同的實現類
1)ArrayBlockingQueue:規定大小的BlockingQueue,其建構函式必須帶一個int引數來指明其大小.其所含的物件是以FIFO(先入先出)順序排序的.
2)LinkedBlockingQueue:大小不定的BlockingQueue,若其建構函式帶一個規定大小的引數,生成的BlockingQueue有大小限制,若不帶大小引數,所生成的BlockingQueue的大小由Integer.MAX_VALUE來決定.其所含的物件是以FIFO(先入先出)順序排序的
3)PriorityBlockingQueue:類似於LinkedBlockQueue,但其所含物件的排序不是FIFO,而是依據物件的自然排序順序或者是建構函式的Comparator決定的順序.
4)SynchronousQueue:特殊的BlockingQueue,對其的操作必須是放和取交替完成的.
3.LinkedBlockingQueue和ArrayBlockingQueue比較起來,它們背後所用的資料結構不一樣,導致LinkedBlockingQueue的資料吞吐量要大於ArrayBlockingQueue,但線上程數量很大時其效能的可預見性低於ArrayBlockingQueue.
*/
public class BlockingQueueTest {
/**定義裝蘋果的籃子*/
public static class Basket{
//籃子,能夠容納3個蘋果
BlockingQueue<String> basket = new ArrayBlockingQueue<String>(3);
//生產蘋果,放入籃子
public void produce() throws InterruptedException{
//put方法放入一個蘋果,若basket滿了,等到basket有位置
basket.put("An apple");
}
//消費蘋果,從籃子中取走
public String consume() throws InterruptedException{
//take方法取出一個蘋果,若basket為空,等到basket有蘋果為止
return basket.take();
}
}
//測試方法
public static void testBasket(){
final Basket basket = new Basket();//建立一個裝蘋果的籃子
//定義蘋果生產者
class Producer implements Runnable{
public void run(){
try{
while(true){
//生產蘋果
System.out.println("生產者準備生產蘋果: " + System.currentTimeMillis());
basket.produce();
System.out.println("生產者生產蘋果完畢: " + System.currentTimeMillis());
//休眠300ms
Thread.sleep(300);
}
}catch(InterruptedException ex){
}
}
}
//定義蘋果消費者
class Consumer implements Runnable{
public void run(){
try{
while(true){
//消費蘋果
System.out.println("消費者準備消費蘋果: " + System.currentTimeMillis());
basket.consume();
System.out.println("消費者消費蘋果完畢: " + System.currentTimeMillis());
//休眠1000ms
Thread.sleep(1000);
}
}catch(InterruptedException ex){
}
}
}
ExecutorService service = Executors.newCachedThreadPool();
Producer producer = new Producer();
Consumer consumer = new Consumer();
service.submit(producer);
service.submit(consumer);
//程式執行5s後,所有任務停止
try{
Thread.sleep(5000);
}catch(InterruptedException ex){
}
service.shutdownNow();
}
public static void main(String[] args){
BlockingQueueTest.testBasket();
}
}