轮询多个线程和CPU使用情况

时间:2011-08-21 16:07:35

标签: java concurrency java.util.concurrent

我接到一个来自用户的作业列表的调用说用户发布了3个作业A,B和C,它们都在自己的线程AT,BT和CT中开始执行,然后我开始监视这3个线程,如果其中一个失败的工作说B失败了,我需要发出A和C信号停止。当所有线程都停止返回时,如果所有线程都失败则返回true。

目前我有一个很大的while循环,它做了50ms的检查和睡眠,这有效,但我想知道我有一个更好的方法来做这个没有任何类型的睡眠,我试着睡觉0ms AFAIK这把我的线程到了cpu que的末尾,但它仍然使用了太多的CPU大约60%。

3 个答案:

答案 0 :(得分: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()抛出异常,从f集中删除futures,迭代集合中的其他元素(即通过其他任务)你提交了),.cancel()他们。必须将Callable编码为可取消,否则对.cancel()的调用将无效。

答案 1 :(得分:0)

您可以将A,B,C作业包装在Runnable中,该{{1}}知道作业失败的时间并且也知道控制线程。当这个包装器检测到作业失败时(异常,运行时条件和不是),它将通知控制线程以进一步操作。

这样您就不必轮询线程,但是您将等待来自包装器错误检测器的信号。

答案 2 :(得分:0)

您可以向作业添加回调,在线程失败的情况下调用该回调。然后回调将继续停止所有线程。