2011-08-21 84 views
1

我有一個接收來自用戶的作業列表打電話說用戶發佈3個項目A,B和C,他們都在自己的線程開始執行AT,BT和CT,然後我開始監視這3個線程,如果其中一個作業失敗,說B失敗了,我需要發信號A和C停止。當所有線程停止返回時,如果一個失敗,則全部成功返回true。輪詢多線程和CPU使用率

目前我有一個很大的while循環做檢查和睡眠50ms,哪些作品,但我想知道我有沒有任何睡眠做這個更好的方式,我試過睡覺0ms AFAIK這使我的線程到cpu que的末尾,但它仍然利用了太多60%左右的cpu。

回答

3

這聽起來像一個用例ExecutorCompletionService

// wrap tasks A, B and C into runnables (or callables if you need some result): 
Callable<Result> taskA = ...; 
Callable<Result> taskB = ...; 
Callable<Result> taskC = ...; 

// create an ExecutorCompletionService 
// to which you must pass an ExecutorService 
// (choose one according to your precise use case) 
// (the newCachedThreadPoolExecutor might not be a sensible choice) 
ExecutorCompletionService e = new ExecutorCompletionService(Executors.newCachedThreadPoolExecutor()); 

Set<Future<Result>> futures = new HashSet<>(); 

// submit your tasks: 
futures.add(e.submit(taskA)); 
futures.add(e.submit(taskB)); 
futures.add(e.submit(taskC)); 

// now call take() on the executor completion service, 
// which will block the calling thread until the first task has completed 
// either succesfully or abruptly (with an exception) 
Future<Result> f = e.take(); 

在此之後,當你調用f.get(),你要麼得到的Result一個實例,否則將拋出一個ExectutionException(包裹由執行拋出的異常) 。任何一個都會立即發生(感謝執行者完成服務)。

然後你會做出相應的反應:如果f.get()拋出一個異常,從futures集中刪除f,通過設置的其他元素迭代(即通過您提交的其他任務),並.cancel()他們。該Callable s必須是編碼爲取消,否則調用.cancel()不會做任何事情。

0

您可以在Runnable,知道當一個作業失敗,也知道該控制線程包住A,B,C作業。當這個包裝器檢測到作業失敗時(異常,運行時條件和不包含的情況),它將通知控制線程進一步操作。

這樣你就不必輪詢線程,但是你會等待從包裝錯誤檢測器的信號。

0

您可以向作業添加回調,在線程失敗的情況下調用該作業。回調將繼續停止所有線程。

+0

但我還是要等我需要返回給用戶一個真/假值,如果一個失敗,假,當所有真正的成功。 –