2013-11-24 83 views
4

我已經閱讀了許多類似的questions。不過,我對答案並不滿意。如何優化線程數加快處理速度

我想建立一個算法,根據平均速度調整線程數。

假設我介紹一個新的線程,任務執行的平均速度增加,這意味着新的線程是好的。然後算法應該嘗試添加另一個線程...直到達到最佳線程數量......

此外,該算法應該跟蹤平均速度。如果在某些點的平均速度下降顯著,讓我們10%的人說(因爲任何原因如我打開不同的應用程序或其他),則算法應該終止一個線程,看看速度上升...

也許存在這樣的API。請給我任何指示或任何代碼示例如何我可以實現這樣的算法

謝謝!

+3

假設兩個不同的程序也做了同樣的事情。你將如何使聯合系統穩定? –

+0

@AlanStokes - 這只是其中一個問題。我要關閉這個。 –

回答

6

我不知道你所描述的自我調節系統,但它聽起來並不複雜的任務,一旦你準備使用線程池。從concurrency包中取出線程池,實現類TimeConsumptionCallable implements Callable,該類包裝其他任何可調用對象,並只測量執行時間。

現在,你只需要改變(增加或減少)數量的工作線程時平均執行時間增加或減少。

但不要忘記,你需要足夠的統計數據你決定改變工作線程的數目了。否則,不依賴於您的應用程序的各種隨機效應可能會導致您的線程池一直增長並且一直下降,從而導致整體性能下降。

5

newCachedThreadPool() V/s newFixedThreadPool表明也許你應該看看ExecutorService.newCachedThreadPool()

創建一個創建新線程需要一個線程池,但會重用以前構造的線程可用時他們。這些池通常會提高執行許多短暫異步任務的程序的性能。調用執行將重用以前構造的線程(如果可用)。如果沒有現有線程可用,則會創建一個新線程並將其添加到池中。 未使用六十秒的線程終止並從緩存中刪除。因此,保持閒置時間足夠長的池不會消耗任何資源。請注意,使用ThreadPoolExecutor構造函數可以創建具有類似屬性但具有不同細節的池(例如,超時參數)。

+1

緩存的ThreadPoolExecutor是不是何時創建一個新的線程,非常聰明。每次添加新任務時,它都會創建一個新的任務,直到達到限制,然後有時會刪除一個,如果太多空閒的話。所以它絕不會優化執行性能。 – TwoThe

2

如果你的線程不會在任何時候封鎖,然後在達到最大運行速度,當你有儘可能多線程的內核,簡單地超過100%的CPU使用率是不可能的。

在其他情況下,衡量新線程增加/減少執行速度的難度非常大,因爲您只需觀察一會兒的時間,並根據下一秒可能完全不同的事情做出假設。

一個想法是使用相結合的執行器類與您指定的隊列。所以你可以測量隊列的大小並根據這個假設做出假設。如果隊列爲空,則線程處於空閒狀態,您可以刪除一個線程。如果隊列填滿,線程無法處理負載,則需要添加更多。如果隊列穩定,你就是對的。

1

您可以通過使用Java的現有的API拿出自己的算法:

公共無效setCorePoolSize(INT corePoolSize)在ThreadPoolExecutor

設置線程的芯數。這將覆蓋構造函數中設置的任何值。

如果新值比當前值小,多餘的現有線程將被當他們未來成爲閒置終止。

如果較大,新的線程將,如果需要的話,可以開始執行任何排隊的任務。

初始化:

ExecutorService service = Executors.newFixedThreadPool(5); // initializaiton 

您的需要的基礎上,通過以下API調整池

((ThreadPoolExecutor)service).setCorePoolSize(newLimit);//newLimit is new size of the pool 

而且很重要的一點:如果隊列已滿,線程數的新價值大於或等於前面定義的maxPoolSize,任務將被拒絕。

設置maxPoolSize時使setCorePoolSize正常工作要小心。