標籤:
BlockingQueue也是java.util.concurrent下的主要用來控制線程同步的工具。
BlockingQueue有四個具體的實作類別,根據不同需求,選擇不同的實作類別
1、ArrayBlockingQueue:一個由數組支援的有界阻塞隊列,規定大小的BlockingQueue,其建構函式必須帶一個int參數來指明其大小.其所含的對象是以FIFO(先入先出)順序排序的。
2、LinkedBlockingQueue:大小不定的BlockingQueue,若其建構函式帶一個規定大小的參數,產生的BlockingQueue有大小限制,若不帶大小參數,所產生的BlockingQueue的大小由Integer.MAX_VALUE來決定.其所含的對象是以FIFO(先入先出)順序排序的。
3、PriorityBlockingQueue:類似於LinkedBlockQueue,但其所含對象的排序不是FIFO,而是依據對象的自然排序次序或者是建構函式的Comparator決定的順序。
4、SynchronousQueue:特殊的BlockingQueue,對其的操作必須是放和取交替完成的。
LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的話,預設最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在隊列滿的時候會阻塞直到有隊列成員被消費,take方法在隊列空的時候會阻塞,直到有隊列成員被放進來。
生產者消費者的範例程式碼:
1 package com.xt.thinks21_7; 2 3 import java.util.concurrent.BlockingQueue; 4 import java.util.concurrent.ExecutorService; 5 import java.util.concurrent.Executors; 6 import java.util.concurrent.LinkedBlockingDeque; 7 8 /** 9 * 使用BlockingQuene類比生產者與消費者10 * 11 * @author Ymmmsick12 *13 */14 public class BlockingQueneTest {15 16 public static void main(String[] args) {17 BlockingQueue<String> quene = new LinkedBlockingDeque<String>(2);18 ExecutorService es = Executors.newCachedThreadPool();19 for (int i = 0; i < 10; i++) {20 es.execute(new Product(quene, "Thread->" + i));21 es.execute(new Consumer(quene));22 }23 24 es.shutdown();25 }26 }27 28 class Product implements Runnable {29 30 private BlockingQueue<String> quene;31 private String name;32 33 public Product(BlockingQueue<String> quene, String name) {34 this.quene = quene;35 this.name = name;36 }37 38 @Override39 public void run() {40 // TODO Auto-generated method stub41 try {42 quene.put(name);43 System.out.println("Product :" + name);44 } catch (InterruptedException e) {45 // TODO Auto-generated catch block46 e.printStackTrace();47 }48 }49 50 }51 52 class Consumer implements Runnable {53 54 private BlockingQueue<String> quene;55 56 public Consumer(BlockingQueue<String> quene) {57 this.quene = quene;58 }59 60 @Override61 public void run() {62 // TODO Auto-generated method stub63 try {64 String t = quene.take();65 System.out.println("Consumer:" + t);66 } catch (InterruptedException e) {67 // TODO Auto-generated catch block68 e.printStackTrace();69 }70 }71 72 }
輸出結果:
Product :Thread->0
Consumer:Thread->0
Product :Thread->1
Product :Thread->2
Consumer:Thread->1
Consumer:Thread->2
Product :Thread->3
Consumer:Thread->3
Product :Thread->4
Consumer:Thread->4
Product :Thread->5
Consumer:Thread->5
Product :Thread->6
Consumer:Thread->6
Product :Thread->7
Consumer:Thread->7
Product :Thread->8
Consumer:Thread->8
Product :Thread->9
Consumer:Thread->9
結論:LinkedBlockingQuene在同一時間段內最多隻能保持兩個對象在隊列,對象溢滿的時候生產者會等待阻塞,對象空置的時候消費者會等待阻塞。
JAVA並發,BlockingQuene