LinkedBlockingQueue的put,add跟offer的區別

LinkedBlockingQueue的put,add和offer的區別 java

      最近在學習<<Java併發編程實踐>>,有不少java.util.concurrent包下的新類。LinkedBlockingQueue就是其中之一,顧名思義這是一個阻塞的線程安全的隊列,底層應該採用鏈表實現。編程

       看其API的時候發現,添加元素的方法居然有三個:add,put,offer。安全

且這三個元素都是向隊列尾部添加元素的意思。因而我產生了興趣,要仔細探究一下他們之間的差異。併發

1.首先看一下add方法:函數

[java]  view plain  copy
 
  1. Inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions, returning true upon success and throwing an IllegalStateException if no space is currently available.   
  2.   
  3. This implementation returns true if offer succeeds, else throws an IllegalStateException.  

        LinkedBlockingQueue構造的時候若沒有指定大小,則默認大小爲Integer.MAX_VALUE,固然也能夠在構造函數的參數中指定大小。LinkedBlockingQueue不接受null。學習

       add方法在添加元素的時候,若超出了度列的長度會直接拋出異常:this

[java]  view plain  copy
 
  1. public static void main(String args[]){  
  2.         try {  
  3.             LinkedBlockingQueue<String> queue=new LinkedBlockingQueue(2);  
  4.               
  5.             queue.add("hello");  
  6.             queue.add("world");  
  7.             queue.add("yes");  
  8.         } catch (Exception e) {  
  9.             // TODO: handle exception  
  10.             e.printStackTrace();  
  11.         }  
  12.     }  
  13. //運行結果:  
  14. java.lang.IllegalStateException: Queue full  
  15.     at java.util.AbstractQueue.add(Unknown Source)  
  16.     at com.wjy.test.GrandPather.main(GrandPather.java:12)  

 

2.再來看一下put方法:spa

[java]  view plain  copy
 
  1. Inserts the specified element at the tail of this queue, waiting if necessary for space to become available.  

      對於put方法,若向隊尾添加元素的時候發現隊列已經滿了會發生阻塞一直等待空間,以加入元素。.net

[java]  view plain  copy
 
  1. public static void main(String args[]){  
  2.         try {  
  3.             LinkedBlockingQueue<String> queue=new LinkedBlockingQueue(2);  
  4.               
  5.             queue.put("hello");  
  6.             queue.put("world");  
  7.             queue.put("yes");  
  8.               
  9.             System.out.println("yes");  
  10.         } catch (Exception e) {  
  11.             // TODO: handle exception  
  12.             e.printStackTrace();  
  13.         }  
  14.     }  
  15. //運行結果:  
  16. //在queue.put("yes")處發生阻塞  
  17. //下面的「yes」沒法輸出  

 

3.最後看一下offer方法:線程

[java]  view plain  copy
 
  1. Inserts the specified element at the tail of this queue if it is possible to do so immediately without exceeding the queue's capacity, returning true upon success and false if this queue is full. When using a capacity-restricted queue, this method is generally preferable to method add, which can fail to insert an element only by throwing an exception.  

   

    offer方法在添加元素時,若是發現隊列已滿沒法添加的話,會直接返回false。

 

[java]  view plain  copy
 
  1. public static void main(String args[]){  
  2.         try {  
  3.             LinkedBlockingQueue<String> queue=new LinkedBlockingQueue(2);  
  4.               
  5.             boolean bol1=queue.offer("hello");  
  6.             boolean bol2=queue.offer("world");  
  7.             boolean bol3=queue.offer("yes");  
  8.               
  9.             System.out.println(queue.toString());  
  10.             System.out.println(bol1);  
  11.             System.out.println(bol2);  
  12.             System.out.println(bol3);  
  13.         } catch (Exception e) {  
  14.             // TODO: handle exception  
  15.             e.printStackTrace();  
  16.         }  
  17.     }  
  18. //運行結果:  
  19. [hello, world]  
  20. true  
  21. true  
  22. false  

 

    好了,居然說了這麼多了,就把從隊列中取元素的方法也順便一說。

從隊列中取出並移除頭元素的方法有:poll,remove,take。

 

總結:

take和put是阻塞的獲取和存儲元素的方法,

poll和offer是不阻塞的獲取元素和存儲元素的方法,而且poll和offer能夠指定超時時間。

add和remove存取元素,隊列滿時add拋異常,隊列空時remove拋異常

 

poll: 若隊列爲空,返回null。

remove:若隊列爲空,拋出NoSuchElementException異常。

take:若隊列爲空,發生阻塞,等待有元素。

相關文章
相關標籤/搜索