2013-04-08 191 views
0

我一直在閱讀關於阻塞隊列和出現的某些問題。我讀過的所有例子都只演示了只有一個消費者和一個生產者線程的情況。問題是:假設我們有1個生產者和3個消費者,並且在當前所有消費者都被稱爲take()方法,但隊列是空的,因此他們都等待出現第一個元素。當消費者線程出現時,哪個線程會採用第一個元素?首先調用take()的消費者線程?Java,被阻塞的隊列

回答

1

當消費者線程出現時,哪個消費者線程將採用第一個元素?首先調用take()的消費者線程?

這與阻塞隊列實現以及JVM有關,但簡短答案很可能是。每個線程都將等待一個條件,等待隊列中的第一個線程將在條件發送時喚醒。

也就是說,你不應該依賴這個功能,因爲它非常依賴於有問題的阻塞隊列以及JVM和OS版本的細節。

+0

這取決於實現,在某些情況下,如'ArrayBlockingQueue',在創建參數時。 – Keppil 2013-04-08 13:52:17

+0

但是,即使在'ArrayBlockingQueue'非公平模式中,也有一個好處,那就是有一個等待線程的隊列,第一個叫'take()'的隊列將被出隊。 – Gray 2013-04-08 13:55:22

+0

那麼在公平模式下會發生什麼?有什麼區別? – 2013-04-08 14:00:58

2

我不知道你能否告訴。真正的問題是:你爲什麼需要知道?所有聽衆應該是等同的。哪一個處理請求並不重要。如果你必須知道,你的設計和實施不正確。

2

檢查ArrayBlockingQueue(int capacity, boolean fair)如果公平爲真,則隊列訪問插入或移除時阻塞的線程,按先進先出順序處理。

1

我同意duffymo,讓多個線程無限期地等待一些新元素在隊列中彈出的想法聽起來沒有很好的結構。另外,如果您需要知道哪一位消費者移除了這個元素,那麼這讓我認爲消費者實際上在做不同的事情,根據消費者的訂單給予不同情況下的不同產出的生命執行take()。如果是這種情況,您可能希望針對不同的線程擁有不同的隊列。

如果你不打算改變你的代碼,那麼讓線程定期執行一次poll呢?

+0

'多個線程無限期地等待某些新元素在隊列中彈出'是一種可接受的設計模式,非常常見。你認爲什麼是錯的?我同意不應該考慮哪個線程得到什麼任務。 – 2013-04-08 15:04:49

+0

是的你是對的。我在腦海裏想到了一個等待元素彈出的不同線程的圖像,這聽起來並不理想,但我在等待元素的線程中看不到任何錯誤。當然,假設消費者做的唯一事情就是消耗元素並執行元素本身的處理。 – user1897690 2013-04-08 16:27:24