2013-08-27 25 views
5

我有一個情況多線程將輪詢單BlockingQueue通過調用take()。我想知道的是以下內容:BlockingQueues和線程訪問順序

如果多個線程正在等待隊列接收項目,他們將被優先考慮按照他們進行調用的次序從隊列中取出項目()或線程從隊列中排隊的順序是否是任意的?

謝謝!

注:我寫我自己的實現了這種事情在過去,但我想知道如果在Java中BlockingQueue實現會做這對我來說。

+1

一般來說,任何多線程應用程序都不應該對線程執行順序做任何假設。有辦法強制執行它,但MT應用程序背後的想法是不應該這樣做。 – Dariusz

+1

有趣的問題,我寫了一個程序 - 沒有固定的順序。 – Tala

+1

[相關問題](http://stackoverflow.com/questions/1301691/java-queue-implementations-which-one)這也討論公平。 –

回答

4

這取決於執行。

如果使用LinkedBlockingQueue,該take()方法檢查與ReentrantLock

public E take() throws InterruptedException { 
    E x; 
    int c = -1; 
    final AtomicInteger count = this.count; 
    final ReentrantLock takeLock = this.takeLock; 
    takeLock.lockInterruptibly(); 
    ... 
} 

// declared as 
private final ReentrantLock takeLock = new ReentrantLock(); // no fairness argument, defaults to false 

javadoc

這個類的構造函數接受一個可選的公平性參數。 如果設置爲true,則在爭用時,鎖定允許授予對最長等待線程的訪問權限。 否則此鎖不保證任何 特定訪問訂單。使用許多 線程訪問公平鎖定的程序可能會顯示較低的整體吞吐量(即速度較慢,往往 慢得多),比使用默認設置的,但有次小 差異獲得鎖和保證缺乏飢餓。 但是請注意,鎖的公平性並不能保證線程調度的公平性。因此,使用公平鎖可以 獲得它多次連續而其他活動線程是 沒有進展,目前不持有鎖的線程之一。另請注意,不定時的tryLock方法不支持公平設置。如果鎖定可用,即使其他線程正在等待,它也將成功地取得成功 。

2

在許多情況下的javadoc何況如果類是「公平」,即阻塞分佈,使所有線程獲得同樣的機會。這並不意味着像「相同的順序」一樣。檢查javadocs是否具有公平性和/或順序的信息。公平的

至少ArrayBlockingQueue運籌學如下:

該類支持訂購等待 生產者和消費者線程的一個可選的公平策略。默認情況下,此訂購不保證爲 。但是,公平性設置爲true的隊列按照FIFO順序授予線程訪問權限。公平性通常會降低吞吐量,但會降低可變性並避免飢餓。

1

它取決於實現,類是否支持用於排序等待生產者和消費者線程的可選公平策略。例如。ArrayBlockingQueue可以是公平的,因爲它具有構造函數ArrayBlockingQueue(int capacity,boolean fair),但LinkedBlockingQueue不能。