2011-08-21 114 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

但我还是要等我需要返回给用户一个真/假值,如果一个失败,假,当所有真正的成功。 –