1. 程式人生 > >並發隊列ConcurrentLinkedQueue和阻塞隊列LinkedBlockingQueue用法

並發隊列ConcurrentLinkedQueue和阻塞隊列LinkedBlockingQueue用法

zed obj 生產者消費者模式 con 不定 每次 實際應用 耗時 true

在Java多線程應用中,隊列的使用率很高,多數生產消費模型的首選數據結構就是隊列(先進先出)。Java提供的線程安全的Queue可以分為阻塞隊列和非阻塞隊列,其中阻塞隊列的典型例子是BlockingQueue,非阻塞隊列的典型例子是ConcurrentLinkedQueue,在實際應用中要根據實際需要選用阻塞隊列或者非阻塞隊列,都不能存放null值。

1、BlockingQueue下有兩個常用子類LinkedBlockingQueue和ArrayBlockingQueue,內部分鏈表和數組實現,要想實現獲取元素和存放元素的線程安全阻塞,那麽只能用裏面線程安全的兩個方法put()和take()來實現,阻塞的意思就是此條線程會處於等待卡死狀態,解鎖的條件是隊列中有另一條線程存入或取出數據了,就會解鎖,說白了就是滿了不能再存,空了不能取,都得等著,就相當於隊列是倉庫,倉庫沒有貨了就生產,倉庫有貨就能消費,鎖條件是notFull和notEmpty,此種隊列多用於生產者消費者模式,new之前最好指定容量大小,不然默認是Integer.MAX_VALUE的大小。

2、ConcurrentLinkedQueue是非阻塞隊列,其沒有put和take方法,可以無限制存,且是線程安全的,N個用戶同時存也能保證每次存放在隊尾而不亂掉,但是其的size()方法會不定時遍歷,所以特耗時,開發時不要用,如果判斷是否有元素可以使用isEmpty()方法,千萬不要用size()>0來判斷是否有元素ConcurrentLinkedQueue的queue.add(obj); 或者 queue.poll(obj);是線程安全的,但是其他方法並沒有保證線程安全,如判斷isEmpty()所以在多線程時還得自己加鎖

synchronized(queue) {    
   if(!queue.isEmpty()) {    
   queue.poll(obj);    
  }    
 }  

  

並發隊列ConcurrentLinkedQueue和阻塞隊列LinkedBlockingQueue用法