簡體   English   中英

線程池執行器

[英]Thread Pool Executor

我正在使用線程池執行程序來更改舊式設計。 詳情如下所示:-

遺留問題:-對於舊式設計,在應用程序啟動時會創建600個線程。 並將它們放置在各個池中,然后在需要時將其拾取,並將任務分配給相應的線程。

新增:-在新設計中,我用執行者服務替換了線程池,如下所示:

 ThreadPoolExecutor thpool = new ThreadPoolExecutor(coreSize,poolsize,...);

我觀察到的是,在執行程序的情況下,啟動時不會創建任何線程。 它們是在客戶端觸發請求時創建的。 結果,與前一個線程相比,在內存中創建的線程要少得多。

但是我的問題是這是正確的方法,因為線程創建也是觸發調用時發生的開銷。

請根據舊方法,在從內存中的客戶端線程或空閑線程進行調用時,處理哪個更繁重的線程創建過程。

還建議使用哪個執行器池以在性能方面獲得最佳結果。

要在啟動時修復600個線程,請嘗試使用java.util.concurrent.Executors.newFixedThreadPool(600);

創建一個線程池,該線程池重用在共享的無邊界隊列上運行的固定數量的線程。 在任何時候,最多nThreads個線程都是活動的處理任務。 如果在所有線程都處於活動狀態時提交了其他任務,則它們將在隊列中等待,直到某個線程可用為止。 如果在關閉之前執行過程中由於執行失敗導致任何線程終止,則在執行后續任務時將使用新線程代替。 池中的線程將一直存在,直到明確將其關閉。

如您所見,文檔沒有告訴我們線程是立即啟動還是按需啟動。

如果絕對希望在啟動時啟動600個線程,則可以發布600個空任務:

for( int i = 0; i < 600; ++i ) {
   executor.submit( new Runnable(){public void run(){/**/}});
}

您可以致電:

thpool.prestartAllCoreThreads();

要么

thpool.prestartCoreThread();

這兩種方法可以啟動一個核心線程(Threads),使它空閑地等待工作。

但我建議您不要這樣做,因為它將直接占用您的資源。

600聽起來很多。 您可能希望將其降低到可用處理器的數量。 或者,如果線程最終等待很多,那么如果您的線程不是100%受CPU限制的話,那么TPE的Runnables就是平均負擔。 假設您有nCPUs=Runtime.getRuntime().availableProcessors()loadFactor作為線程上的平均負載(在測試或更好的是,持續監控中觀察到)。 然后,您將使用nThreads = nCPUs / loadFactor,並希望loadFactor不為零。

您也可以使用較小的coresize和較大的poolsize,但隨后需要一個有界隊列。 在這種情況下,如果隊列已滿,則TPE將啟動新線程,直到達到池大小為止。 如果您的大部分工作是在coresize范圍內處理的,那么線程創建就不會太頻繁,開銷也不是問題。 但是,即使這可能最終會在TPE的最大線程運行時阻塞。

如果您的工作是某種傳入的工作,例如從其他連接的套接字讀取而不會阻塞,則可以創建一個無界的中間隊列以使入站處理最終不會在您的TPE處阻塞,並使用另一個線程從中間線程提交作業到TPE隊列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM