1. 程式人生 > >Java 經典面試題:聊一聊 JUC 下的 LinkedBlockingQueue

Java 經典面試題:聊一聊 JUC 下的 LinkedBlockingQueue

本文聊一下 JUC 下的 LinkedBlockingQueue 佇列,先說說 LinkedBlockingQueue 佇列的特點,然後再從原始碼的角度聊一聊 LinkedBlockingQueue 的主要實現~ LinkedBlockingQueue 有以下特點: - **LinkedBlockingQueue 是阻塞佇列,底層是單鏈表實現的**~ - **元素從佇列尾進隊,從佇列頭出隊,符合FIFO**~ - **可以使用 Collection 和 Iterator 兩個介面的所有操作,因為實現了兩者的介面**~ - **LinkedBlockingQueue 佇列讀寫操作都加了鎖,但是讀寫用的是兩把不同的鎖,所以可以同時讀寫操作**~ LinkedBlockingQueue 佇列繼承了 `AbstractQueue` 類,實現了 `BlockingQueue` 介面,LinkedBlockingQueue 主要有以下介面: ```java //將指定的元素插入到此佇列的尾部(如果立即可行且不會超過該佇列的容量) //在成功時返回 true,如果此佇列已滿,則拋IllegalStateException。 boolean add(E e); //將指定的元素插入到此佇列的尾部(如果立即可行且不會超過該佇列的容量) // 將指定的元素插入此佇列的尾部,如果該佇列已滿, //則在到達指定的等待時間之前等待可用的空間,該方法可中斷 boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException; //將指定的元素插入此佇列的尾部,如果該佇列已滿,則一直等到(阻塞)。 void put(E e) throws InterruptedException; //獲取並移除此佇列的頭部,如果沒有元素則等待(阻塞), //直到有元素將喚醒等待執行緒執行該操作 E take() throws InterruptedException; //獲取並移除此佇列的頭,如果此佇列為空,則返回 null。 E poll(); //獲取並移除此佇列的頭部,在指定的等待時間前一直等到獲取元素, //超過時間方法將結束 E poll(long timeout, TimeUnit unit) throws InterruptedException; //從此佇列中移除指定元素的單個例項(如果存在)。 boolean remove(Object o); //獲取但不移除此佇列的頭元素,沒有則跑異常NoSuchElementException E element(); //獲取但不移除此佇列的頭;如果此佇列為空,則返回 null。 E peek(); ``` LinkedBlockingQueue 佇列的讀寫方法非常的多,但是常用的是 `put()`、`take()`方法,因為它們兩是阻塞的,所以我們就從原始碼的角度來聊一聊 LinkedBlockingQueue 佇列中這兩個方法的實現。 先來看看 `put()`方法,原始碼如下: ```java public void put(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); // 預先設定 c 的值為 -1,表示失敗 int c = -1; Node