2011-08-31 72 views
1

我有一個ThreadPoolExecutor是用一個無界隊列(LinkedBlockingQueue)和一個核心和最大池大小設置爲cpus數(比如說4)構造的。我不明白這個ThreadPoolExecutor行爲

每當我得到一個RejectedExecutionException異常。執行器處於運行狀態。我的理解是,這不應該發生在無邊界的隊列中。

我一直沒有能夠在調試器中看到發生了什麼,但是從堆棧跟蹤看起來像在ThreadPoolExecutor.execute中,workQueue.offer返回false,所以它跳轉到位它試圖啓動一個新的線程。但是poolSize已經在最大值,所以它會拋出被拒絕的執行異常。

我不太明白這一點。

但是無論如何,我是否應該使最大池大小比核心池大小大一點?

+1

看看這個優秀的答案,並upvote它:http://stackoverflow.com/questions/1800317/impossible-to-make-a-cached-thread-pool-with-a-size-limit/1800583# 1800583 –

+2

這個答案只是證實@deliciousirony看到的行爲不應該發生。 – Thilo

+0

你可以發表一些代碼嗎? – jiggy

回答

2

LinkedBlockingQueue.offer()返回false當它在其容量。如果容量未指定,則使用Integer.MAX_VALUE

添加2147483647個任務多於您的池大小時會發生這種情況嗎?

+0

是的,我們可能正在排隊。我不認爲這是可能的,但現在我是。沒有別的東西會有意義。謝謝。 – marathon

2
  1. 即使是「無界的」LinkedBlockingQueue實際上也是bounded at Integer.MAX_VALUE。是的,你不可能達到這個限度,但是「一旦你消除了不可能......」。
  2. 你有多確定執行者仍處於RUNNING狀態?在我的源代碼中,狀態檢查和offer()調用都位於同一行,因此您無法在堆棧跟蹤中區分它們。
+0

雖然我同意非RUNNING狀態會這樣做,但帶狀態檢查和offer()調用的行根本不在堆棧跟蹤中。堆棧跟蹤將包含拒絕(命令)行。 –

+0

我開始認爲我們實際上正在排隊。這個應用程序運行在64位虛擬機上,並提供幾乎無限的內存。負載是巨大的,如果工作人員因任何原因而停滯不前,我們可能會在幾個小時內填補這個隊列。我要檢查LinkedBlockingQueue,看看是否是這樣。謝謝。 – marathon