執行緒池中常用的阻塞佇列簡述

2021-09-04 09:09:33 字數 2625 閱讀 7779

基於陣列的阻塞佇列,有界佇列,按照先進先出(fifo)的形式,初始化是必須指定capacity.看一下原始碼:

/**第一種構造方法,指定初始容量*/

public arrayblockingqueue(int capacity)

/**第二種構造方法,指定初始容量和乙個標誌,true:公平鎖,false:非公平鎖*/

public arrayblockingqueue(int capacity, boolean fair)

/**第三種構造方法,指定初始容量和乙個標誌,true:公平鎖,false:非公平鎖;指定乙個初始化的集合*/

public arrayblockingqueue(int capacity, boolean fair,

collection<? extends e> c)

} catch (arrayindexoutofbound***ception ex)

count = i;

putindex = (i == capacity) ? 0 : i;

} finally

}

基於鍊錶的阻塞佇列,元素按照先進先出(fifo)的策略。原始碼如下:

/**無界佇列*/ 

public linkedblockingqueue()

/**指定初始化容量*/

public linkedblockingqueue(int capacity)

/**無界佇列,並指定初始化的集合*/

public linkedblockingqueue(collection<? extends e> c)

count.set(n);

} finally

}

容量為0,不儲存任務,通俗地講就是有乙個處理乙個。原始碼如下:

/**第一種無參,this指定的是第二種構造方法*/

public synchronousqueue()

/**第二種,指定fair true:雙端佇列 false:雙端棧*/

public synchronousqueue(boolean fair)

這是乙個無界有序的阻塞佇列,排序規則和之前介紹的priorityqueue一致,只是增加了阻塞操作。同樣的該佇列不支援插入null元素,同時不支援插入非comparable的物件。它的迭代器並不保證佇列保持任何特定的順序,如果想要順序遍歷,考慮使用arrays.sort(pq.toarray())。該類不保證同等優先順序的元素順序,如果你想要強制順序,就需要考慮自定義順序或者是comparator使用第二個比較屬性。原始碼如下:

/**第一種,建立容量的11的佇列*/ 

public priorityblockingqueue()

/**第二種,指定初始化容量*/

public priorityblockingqueue(int initialcapacity)

/**第三種,指定初始化容量和比較規則*/

public priorityblockingqueue(int initialcapacity,

comparator<? super e> comparator)

/**第四種,指定初始化集合,使用鎖*/

public priorityblockingqueue(collection<? extends e> c)

else if (c instanceof priorityblockingqueue<?>)

object a = c.toarray();

int n = a.length;

// if c.toarray incorrectly doesn't return object, copy it.

if (a.getclass() != object.class)

a = arrays.copyof(a, n, object.class);

if (screen && (n == 1 || this.comparator != null))

this.queue = a;

this.size = n;

if (heapify)

heapify();

}

它使用如下方法進行擴容:

/***/ 

private void trygrow(object array, int oldcap)

if (newcap > oldcap && queue == array)

newarray = new object[newcap];

} finally

}if (newarray == null) // back off if another thread is allocating

thread.yield();

lock.lock();

if (newarray != null && queue == array)

}

其先放開了鎖,然後通過cas設定allocationspinlock來判斷哪個執行緒獲得了擴容許可權,如果沒搶到許可權就會讓出cpu使用權。最後還是要鎖住開始真正的擴容。擴容許可權爭取到了就是計算大小,分配陣列。擴容的大小時原有的一倍。

執行緒池中為什麼要使用阻塞佇列?

在乙個task提交到執行緒池時,假設可以被執行緒池中的乙個執行緒執行,則進行以下過程 exeute addworker runnable command,boolean core workers.add w 啟動執行緒執行任務 獲取全域性鎖reentrantlock mainlock 具體原始碼如下...

執行緒安全的佇列 阻塞佇列

queue佇列 先進先出,兩個執行緒同時操作同乙個佇列,執行緒是不安全的 blockingqueue阻塞佇列 先進先出,執行緒是安全,阻塞佇列中維護了鎖,用於進出佇列。一般阻塞佇列用於生產者和消費者模式。arrayblockingqueue 1 基於陣列的阻塞佇列。2 維護的是定長陣列,初始化的時候...

13 執行緒池常用的阻塞佇列有哪些?

執行緒池內部結構 執行緒池的內部結構主要由四部分組成,如圖所示。阻塞佇列 執行緒池中的這四個主要組成部分最值得我們關注的就是阻塞佇列了,如 所示,不同的執行緒池會選用不同的阻塞佇列。左側是執行緒池,右側為它們對應的阻塞佇列,你可以看到 5 種執行緒池對應了 3 種阻塞佇列,我們接下來對它們進行逐一的...