1.ArrayBlockingQueue:基於數組實現的一個阻塞隊列,在創建ArrayBlockingQueue對象時必須制定容量大小。 並且可以指定公平性與非公平性,預設情況下為非公平的,即不保證等待時間最長的隊列最優先能夠訪問隊列。 2.ArrayBlockingQueue內部通過Object[ ...
1.ArrayBlockingQueue:基於數組實現的一個阻塞隊列,在創建ArrayBlockingQueue對象時必須制定容量大小。
並且可以指定公平性與非公平性,預設情況下為非公平的,即不保證等待時間最長的隊列最優先能夠訪問隊列。
2.ArrayBlockingQueue內部通過Object[]數組保存數據的,也就是說ArrayBlockingQueue本質上是通過數組實現的。
ArrayBlockingQueue的大小,即數組的容量是在創建創建ArrayBlockingQueue時候指定的。
3.如下圖所示,ArrayBlockingQueue和ReentrantLock是組合關係,ArrayBlockingQueue中包含一個ReentrantLock對象。
ReentrantLock是可重入的互斥鎖。ArrayBlockingQueue就是根據ReentrantLock互斥鎖實現"多線程對共用資源的訪問"。
ReentrantLock分為公平鎖和非公平鎖,關於具體使用公平鎖還是非公平鎖,在創建ArrayBlockingQueue時可以指定;
而且,ArrayBlockingQueue預設會使用非公平鎖。
4.ArrayBlockingQueue和Condition是組合關係,ArrayBlockingQueue中包含兩個Condition對象(notEmpty和notFull)。
使用通知模式實現:所謂通知模式,當生產者往滿的隊列裡面添加元素的時候,會阻塞生產者(調用Condition notFull.await()進行等待);
當消費者消費了一個隊列中的元素後,會通知(調用Condition notFull.signal()喚醒生產者)生產者當前隊列可用。
反之,當消費者消費的時候,發現隊列是空的,則消費者會被阻塞(通過Condition的 notEmpty.await()進行等待),
當生產者插入了隊列中的一個元素後,則會調用notEmpty.signal()喚醒消費者繼續消費。
package com.demo.zlearn.queue; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; public class ArrayBlockingQueueDemo { public static void main(String[] args) throws Exception { BlockingQueue queue = new ArrayBlockingQueue(5,true); Producer producer = new Producer(queue); Consumer consumer1 = new Consumer(queue,1000); new Thread(producer).start(); new Thread(consumer1).start(); } } class Producer implements Runnable{ protected BlockingQueue queue = null; public Producer(BlockingQueue queue) { this.queue = queue; } public void run() { try { for(int i=0;i<10;i++){ System.out.println("put:"+i); queue.put("AA"); Thread.sleep(4000); } } catch (InterruptedException e) { e.printStackTrace(); } } } class Consumer implements Runnable{ protected BlockingQueue queue = null; private long sleepTimes = 0; public Consumer(BlockingQueue queue,long sleepTimes) { this.queue = queue; this.sleepTimes = sleepTimes; } public void run() { try { while(true){ System.out.println("isEmpty:"+queue.isEmpty()+"\n"+ "size:"+queue.size()+"\n"+ "remainingCapacity:"+queue.remainingCapacity()+"\n" + "take:"+queue.take()+"\n"+ "sleepTimes:"+sleepTimes); //take 如果隊列為空,則阻塞 System.out.println("-----------------------"); Thread.sleep(sleepTimes); } } catch (InterruptedException e) { e.printStackTrace(); } } }
----------------------------------------------------------------------------------------------------------------------
put:0
isEmpty:true
size:0
remainingCapacity:5
take:AA
sleepTimes:1000
-----------------------
put:1
isEmpty:true
size:0
remainingCapacity:5
take:AA
sleepTimes:1000
-----------------------
put:2
isEmpty:true
size:0
remainingCapacity:5
take:AA
sleepTimes:1000
-----------------------
put:3
isEmpty:true
size:0
remainingCapacity:5
take:AA
sleepTimes:1000
-----------------------