LinkedBlockingQueue原理分析

2022-02-11 07:18:25 字數 2515 閱讀 3570

linkedblockingqueue也是乙個阻塞佇列,相比於arrayblockingqueue,他的底層是使用鍊錶實現的,而且是乙個可有界可無界的佇列,在生產和消費的時候使用了兩把鎖,提高併發,是乙個高效的阻塞佇列,下面就分析一下這個佇列的原始碼。

//鍊錶節點定義

static class node

}//容量

private final int capacity;

//佇列中元素個數

private final atomicinteger count = new atomicinteger();

//佇列的首節點

transient nodehead;

//佇列的未節點

private transient nodelast;

/** lock held by take, poll, etc */

//消費者的鎖

private final reentrantlock takelock = new reentrantlock();

/** wait queue for waiting takes */

private final condition notempty = takelock.newcondition();

/** lock held by put, offer, etc */

//生產者的鎖

private final reentrantlock putlock = new reentrantlock();

/** wait queue for waiting puts */

private final condition notfull = putlock.newcondition();

//預設構造方法,無界

public linkedblockingqueue()

//可以傳入容量大小,有界

public linkedblockingqueue(int capacity)

take()方法

public e take() throws

interruptedexception

//執行消費

x =dequeue();

//先賦值,後自減

c =count.getanddecrement();

if (c > 1)

//如果佇列中還有值,喚醒別的消費者

notempty.signal();

} finally

//佇列中還有要給剩餘空間

if (c ==capacity)

//喚醒生產者執行緒

signalnotfull();

return

x; }

進入dequeue()方法

//通過這個方法可以看出,鍊錶的首節點的值是null,每次獲取元素的時候

//先把首節點乾掉,然後從第二個節點獲取值

private e dequeue()

poll()方法

public e poll() 

} finally

if (c == capacity)

signalnotfull();

return x;

}

poll(long timeout, timeunit unit)

這個方法和上面的區別就是加入了時延,在規定的時間沒有消費成功,就返回失敗。

add()方法

public boolean add(e e)

直接呼叫父類abstractqueue的方法

offer(e e)方法

public boolean offer(e e) 

} finally

if (c == 0)

//說明裡面有乙個元素,喚醒消費者

signalnotempty();

return c >= 0;

}

進入enqueue()方法

private void enqueue(nodenode)

直接放到鍊錶的尾部

offer(e e, long timeout, timeunit unit)

和poll(e e,long timeout,timeunit unit)相反。

put(e e)方法

public void put(e e) throws interruptedexception 

enqueue(node);

c = count.getandincrement();

if (c + 1 < capacity)

notfull.signal();

} finally

if (c == 0)

signalnotempty();

}

總體來說比較簡單,下面就列一下lindedblockingqueue的特點:

LinkedBlockingQueue 原始碼學習

linkedblockingqueue是乙個由單向鍊錶實現的阻塞佇列,該佇列按照先進先出的原則對元素進行排序。隊尾插入元素,對頭刪除元素。在構造linkedblockingqueue時可以指定容量大小,若未指定元素,則容量大小為integer.max value.1.以下為linkedblockin...

LinkedBlockingQueue原始碼深入解析

鍊錶 static class node 未指定的話,容量為integer最大值 private final int capacity 當前元素數量 private final atomicinteger count newatomicinteger 頭節點 transient node head ...

LinkedBlockingQueue原始碼理解

一 類介紹 基於鍊錶實現的fifo阻塞佇列實現類。二 屬性介紹 鍊錶節點 static class node 佇列容量,沒指定時容量為 integer.max value private final int capacity 佇列內當前元素個數,保證原子性的增減元素 private final at...