2010-10-04 32 views
1

我想調一個線程,其執行以下操作:的ThreadPoolExecutor - ArrayBlockingQueue ...等待它刪除的元素之前形成隊列

線程池只有1線程[CorePoolSize =0, maxPoolSize = 1]

隊列使用是一個ArrayBlockingQueue

Quesize = 20

背景:
線程嘗試讀取請求並對其執行操作。然而,最終的請求增加了很多,線程總是很忙,並且消耗1個CPU,這使得它成爲一個資源管理器。

我想這樣做,而是在間隔中對請求進行採樣並處理它們。其他請求可以安全地忽略。

我所要做的就是在「操作」函數中進行睡眠,以便線程每次睡眠一段時間並釋放CPU。

Quesiton:
不過,我想知道是否有使用基本上自身休眠它讀取下一個元素之前的某個時候隊列的方式。這將是理想的,因爲在執行過程中休眠任務並保持執行不完整對我來說聽起來並不合適。

請讓我知道如果您有任何其他建議以及對任務

感謝。

編輯: 我添加了一個後續問題here 糾正maxpool大小爲1 [寫在一個急速] ..感謝蒂姆指出。

+1

這不是一個真正的「資源豬」,有很多工作要做。你真的想要人爲地減緩請求嗎?爲什麼請求(客戶端?)發送得比他們可以處理的速度快?這是不可持續的。 – AngerClown 2010-10-05 00:19:26

+0

好點。如果客戶發出很多因完整隊列而被拒絕的請求,那麼他們正在浪費可能在客戶端和執行程序之間更好地平衡的CPU。隊列是一個緩衝區,可以隨時間「平滑」負載;拒絕應該是罕見的,不是常規的。 – erickson 2010-10-05 00:27:23

+0

客戶不是真正意義上的請求者的專用客戶端。請求者有一個專用客戶端,根據請求的數量進行擴展。我正在工作的客戶端就像是一個額外的日誌記錄工具,監控操作類型..採樣仍然很好,以獲取請求圖片..希望是有道理的。 – codeObserver 2010-10-05 00:55:44

回答

1

不,你不能讓線程在池中休眠。如果隊列中有任務,它將被執行。

在排隊的任務中暫停是強制線程閒置而不管排隊的任務的唯一方法。現在,「睡眠」不必與「工作」在同一個任務中,您可以在每個真實任務之後排隊一個單獨的休息任務,這可能會使實施更加清晰。更重要的是,如果工作是返回結果的Callable,則分離爲兩個任務將允許您儘快獲得結果。

作爲一種改進,不是在每個任務之間的固定時間間隔內休眠,而是可以將執行「限制」到指定的速率。這將允許您避免在任務之間不必要的等待,同時避免在指定的時間間隔內執行太多任務。你可以用read another answer of mine來實現這個簡單的方法,使用DelayQueue

1

你可以繼承線程池,並覆蓋beforeExecute休眠一段時間:

@Overrides 
protected void beforeExecute(Thread t, 
         Runnable r){ 
    try{ 
     Thread.sleep(millis); // will sleep the correct thread, see JavaDoc 
    } 
    catch (InterruptedException e){} 

    } 

但看到人爲放慢隊列可能不是一個好主意AngerClown的評論。

+0

謝謝,Thilo ..我認爲BeforeExecute可能會做到這一點。如果工作正常,將會做出更改並接受答案:)。保持線程打開的情況下,有更多的想法:) – codeObserver 2010-10-05 20:57:19

+0

+1提到beforeExecute方法。人們有時非常執着於ExecutorService抽象,他們往往忘記了ThreadPoolExecutor實現也有一些整潔的產品。 – 2010-10-05 22:52:29

+0

我試着用這種方法修補。有趣的是,@times beforeExecute()被調用,然後立即執行任務而不休眠,然後在休眠時間結束後重新執行任務。我正在使用線程池,並且只有一個線程[請參閱我的問題中的詳細信息] ..我是否缺少某些內容? – codeObserver 2010-10-06 23:04:38

1

這可能對您不適用,但您可以嘗試將執行程序的線程優先級設置爲低。

本質上,創建ThreadPoolExecutor與自定義ThreadFactory。讓ThreadFactory.newThread()方法返回優先級爲Thread.MIN_PRIORITY的線程。這將導致您使用的執行程序服務僅在有可用內核運行時才被調度。

含義:在嚴格使用時間分片的系統中,如果整個程序中沒有其他線程具有更高的優先級請求被調度,則只會給予一個時間片來執行。根據您的應用程序的實際情況而定,您可能會每隔一段時間安排一次,否則您可能根本無法安排。

+0

謝謝..我已經考慮過這種方法,但恐怕它可能會讓我的線程餓死。另外,我的線程正在嘗試對數據進行採樣,因此我想要一個真實的世界圖片來說明發生了什麼......這樣做可能會使樣本偏斜到只有CPU處於低電平的時間......這會破壞線程的目的。線程執行的任務也非常小[但是任務太多],所以我認爲睡眠可能會更好。同意? – codeObserver 2010-10-05 23:32:50

+0

是的,同意了。我認爲蒂羅的解決方案是最好的,這就是爲什麼我投了票。 – 2010-10-06 00:00:46

1

線程消耗100%CPU的原因是因爲它的工作量比它能處理的要多。在任務之間添加延遲無法解決此問題。這隻會讓事情變得更糟。

相反,你應該看看爲什麼你的任務消耗了太多的CPU,與一個分析器,並改變它們,以便消耗更少的CPU,直到你發現你的線程能夠跟上,它不再消耗100%的CPU。

+0

這是一個明顯的答案......它就像Facebook太忙,並延遲登錄以防止人們使用網絡。 – 2010-12-25 22:28:16

+0

@Javier,facebook幾乎無法控制請求的進入速度。有些人試圖故意讓服務器負載過重,看看會發生什麼。你的代碼可能會假設工作負載是「友善的」 – 2010-12-26 08:23:03