當生產者試圖向BlockingQueue中放入元素時,如果該隊列已滿,則該線程被阻塞;當消費者試圖從BlockingQueue取出元素時,如果該隊列爲空,則該線程被阻塞。
package bloc;
import java.util.concurrent.*;
public class BlockingQueueTest
{
public static void main(String[] args)
throws Exception
{
// 定義一個長度爲2的阻塞隊列
BlockingQueue<String> bq = new ArrayBlockingQueue<>(2);
bq.put("Java"); // 與bq.add("Java"、bq.offer("Java")相同
bq.put("Java"); // 與bq.add("Java"、bq.offer("Java")相同
bq.put("Java"); // ① 阻塞線程。
}
}
package bloc;
import java.util.concurrent.*;
class Producer extends Thread
{
private BlockingQueue<String> bq;
public Producer(BlockingQueue<String> bq)
{
this.bq = bq;
}
public void run()
{
String[] strArr = new String[]
{
"Java",
"Struts",
"Spring"
};
for (int i = 0 ; i < 999999999 ; i++ )
{
System.out.println(getName() + "生產者準備生產集合元素!");
try
{
Thread.sleep(200);
// 嘗試放入元素,如果隊列已滿,線程被阻塞
bq.put(strArr[i % 3]);
}
catch (Exception ex){ex.printStackTrace();}
System.out.println(getName() + "生產完成:" + bq);
}
}
}
class Consumer extends Thread
{
private BlockingQueue<String> bq;
public Consumer(BlockingQueue<String> bq)
{
this.bq = bq;
}
public void run()
{
while(true)
{
System.out.println(getName() + "消費者準備消費集合元素!");
try
{
Thread.sleep(200);
// 嘗試取出元素,如果隊列已空,線程被阻塞
bq.take();
}
catch (Exception ex){ex.printStackTrace();}
System.out.println(getName() + "消費完成:" + bq);
}
}
}
public class BlockingQueueTest2
{
public static void main(String[] args)
{
// 創建一個容量爲1的BlockingQueue
BlockingQueue<String> bq = new ArrayBlockingQueue<>(1);
// 啓動3條生產者線程
new Producer(bq).start();
new Producer(bq).start();
new Producer(bq).start();
// 啓動一條消費者線程
new Consumer(bq).start();
}
}
ArrayBlockingQueue
一個由數組支持的有限阻塞隊列(其大小在創建的時候就被確定,並且不能在修改)。此隊列裏存儲的元素順序是FIFO(first-in-first-out),是一個很標準的普通隊列,也是我們最常使用到的阻塞隊列。其頭部的元素是在隊列帶的時間最長,尾部元素在隊列中呆的時間最短,新來的元素是插在尾部的,而當隊列獲取元素時是從頭部獲取的。如果試圖將一個元素put到一個full狀態的隊列,這個操作就會被阻塞,直到隊列有空位置。如果從一個empty隊列獲取新的元素同樣也會被阻塞,知道有元素可獲取。
DelayQueue
此隊列是一個無界限的隊列,只有當他的元素在隊列中超過規定時間了他纔可以被取出來,其頭部是超期時間最長的元素,尾部就是超期最短(或還未過期)的元素。如果還沒有過期的元素,那麼就不存在頭部了,將直接返當回null,他的隊列調用了元素的getDelay()方法返回的值小於或等於0就表示過期了。
這個隊列不是所有的元素都可以放進去的,必須是實現了Delayed接口的類對象纔可以放進去,否則就會報類型轉換異常,
LinkedBlockingQueue
是一個基於連接節點的任意大小容量的隊列,這個隊列的順序是FIFO,其頭部是存入隊列最早的元素,尾部是存入隊列最晚的元素,每次都是講元素插入尾部,從頭部取出元素。LinkedBlockingQueue:比ArrayBlockingQueue有更大的吞吐量,但是在併發的情況下其性能是不可預測的。
http://blog.csdn.net/u012481172/article/details/50469690 參考鏈接