1. 程式人生 > >轉: 【Java並發編程】之二十一:並發新特性—阻塞隊列和阻塞棧(含代碼)

轉: 【Java並發編程】之二十一:並發新特性—阻塞隊列和阻塞棧(含代碼)

err 退出 link rac gb2312 com void throws pbo

轉載請註明出處:http://blog.csdn.net/ns_code/article/details/17511147


阻塞隊列

阻塞隊列是Java 5並發新特性中的內容,阻塞隊列的接口是Java.util.concurrent.BlockingQueue,它有多個實現類:ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue等,用法大同小異,具體可查看JDK文檔,這裏簡單舉例看下ArrayBlockingQueue,它實現了一個有界隊列,當隊列滿時,便會阻塞等待,直到有元素出隊,後續的元素才可以被加入隊列。

看下面的例子:

[java] view plain copy
  1. import java.util.concurrent.BlockingQueue;
  2. import java.util.concurrent.ArrayBlockingQueue;
  3. public class BlockingQueueTest{
  4. public static void main(String[] args) throws InterruptedException {
  5. BlockingQueue<String> bqueue = new ArrayBlockingQueue<String>(20);
  6. for (int i = 0; i < 30; i++) {
  7. //將指定元素添加到此隊列中
  8. bqueue.put("加入元素" + i);
  9. System.out.println("向阻塞隊列中添加了元素:" + i);
  10. }
  11. System.out.println("程序到此運行結束,即將退出----");
  12. }
  13. }
輸出結果如下:

技術分享

從執行結果中可以看出,由於隊列中元素的數量限制在了20個,因此添加20個元素後,其他元素便在隊列外阻塞等待,程序並沒有終止。

如果隊列已滿後,我們將隊首元素移出,並可以繼續向阻塞隊列中添加元素,修改代碼如下:

[java] view plain copy
  1. import java.util.concurrent.BlockingQueue;
  2. import java.util.concurrent.ArrayBlockingQueue;
  3. public class BlockingQueueTest{
  4. public static void main(String[] args) throws InterruptedException {
  5. BlockingQueue<String> bqueue = new ArrayBlockingQueue<String>(20);
  6. for (int i = 0; i < 30; i++) {
  7. //將指定元素添加到此隊列中
  8. bqueue.put("" + i);
  9. System.out.println("向阻塞隊列中添加了元素:" + i);
  10. if(i > 18){
  11. //從隊列中獲取隊頭元素,並將其移出隊列
  12. System.out.println("從阻塞隊列中移除元素:" + bqueue.take());
  13. }
  14. }
  15. System.out.println("程序到此運行結束,即將退出----");
  16. }
  17. }
執行結果如下: 技術分享 從結果中可以看出,當添加了第20個元素後,我們從隊首移出一個元素,這樣便可以繼續向隊列中添加元素,之後每添加一個元素,便從將隊首元素移除,這樣程序便可以執行結束。

阻塞棧

阻塞棧與阻塞隊列相似,只是它是Java 6中加入的新特性,阻塞棧的接口java.util.concurrent.BlockingDeque也有很多實現類,使用方法也比較相似,具體查看JDK文檔。

下面同樣給出一個簡單的例子:

[java] view plain copy
  1. import java.util.concurrent.BlockingDeque;
  2. import java.util.concurrent.LinkedBlockingDeque;
  3. public class BlockingDequeTest {
  4. public static void main(String[] args) throws InterruptedException {
  5. BlockingDeque<String> bDeque = new LinkedBlockingDeque<String>(20);
  6. for (int i = 0; i < 30; i++) {
  7. //將指定元素添加到此阻塞棧中
  8. bDeque.putFirst("" + i);
  9. System.out.println("向阻塞棧中添加了元素:" + i);
  10. }
  11. System.out.println("程序到此運行結束,即將退出----");
  12. }
  13. }
執行結果如下:

技術分享

程序依然會阻塞等待,我們改為如下代碼:

[java] view plain copy
  1. import java.util.concurrent.BlockingDeque;
  2. import java.util.concurrent.LinkedBlockingDeque;
  3. public class BlockingDequeTest {
  4. public static void main(String[] args) throws InterruptedException {
  5. BlockingDeque<String> bDeque = new LinkedBlockingDeque<String>(20);
  6. for (int i = 0; i < 30; i++) {
  7. //將指定元素添加到此阻塞棧中
  8. bDeque.putFirst("" + i);
  9. System.out.println("向阻塞棧中添加了元素:" + i);
  10. if(i > 18){
  11. //從阻塞棧中取出棧頂元素,並將其移出
  12. System.out.println("從阻塞棧中移出了元素:" + bDeque.pollFirst());
  13. }
  14. }
  15. System.out.println("程序到此運行結束,即將退出----");
  16. }
  17. }
執行結果如下: 技術分享

從結果中可以看出,當添加了第20個元素後,我們從將棧頂元素移處,這樣便可以繼續向棧中添加元素,之後每添加一個元素,便將棧頂元素移出,這樣程序便可以執行結束。





轉: 【Java並發編程】之二十一:並發新特性—阻塞隊列和阻塞棧(含代碼)