2009-05-21 55 views

回答

1

我的解釋是,你有一堆Callable對象需要在一定的時間間隔進行輪詢。如果您使用線程池,麻煩的是該池將被最慢的成員所污染,並且更快的成員將被餓死。

聽起來你可以控制調度,所以你可能會考慮一種指數退避的方法。也就是說,在Callable X運行(也許超時)之後,您需要等待2秒而不是1秒鐘,然後重新安排它。如果它仍然失敗,請轉到4s,然後是8s等。如果您使用ScheduledThreadPoolExecutor,則它具有內置的方法來執行此操作,從而允許您在一段延遲後安排執行。

如果你設置了一個恆定的超時時間,這個策略將減少你的池對於慢速池的壟斷的敏感度。完全擺脫這個問題是非常困難的。正如你所說,爲每個查詢對象使用單獨的線程確實是確保您不會餓死的唯一方法,並且這可能非常耗費資源。

另一種策略是把你的游泳池變成一個快一個慢一個。如果一個對象超時(比如超過N次),則將其移動到慢速緩衝池。這可以讓你的快速游泳池保持快速,而慢速的游泳池則可以相互阻擋,至少它們不會堵塞快速游泳池。如果他們有一段時間有很好的統計數據,你可以再次將他們提升到快速池。

0

只要您submit a Callable您收到Future - 處理未來的結果。您可以決定等待其完成一段時間:

Future<String> future = executorService.submit(callable); 
try { 
    future.get(1, TimeUnit.SECONDS); 
} catch (TimeoutException e) { 
    future.cancel(true); 
} catch ... 

使用超時調用可讓您在任務尚未完成時收到異常。這不區分未開始的任務和已開始但未完成的任務。另一方面,cancel將採用布爾參數mayStopIfRunning,因此您可以選擇只取消尚未安排的任務。

0

我同意robbotic ......實施「cachedThreadPool」將解決你的問題,因爲這將線程數限制在同一時間的最佳水平有這將釋放你的未利用的資源超時

相關問題