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

发布于 2024-11-30 19:26:29 字数 307 浏览 3 评论 0原文

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

目前我有一个很大的 while 循环,可以进行检查并休眠 50 毫秒,这可以工作,但我想知道是否有更好的方法可以在不进行任何休眠的情况下执行此操作,我尝试休眠 0 毫秒 AFAIK,这使我的线程结束cpu que,但它仍然使用了太多的 cpu 大约 60%。

I have a call that receives a list of jobs from the user say user posted 3 jobs A, B and C, they all start execution in their own threads AT,BT and CT, then I start monitoring these 3 threads, if one of the jobs fail say B failed, I need to signal A and C to stop. When all threads stopped return, when all succeeds true if one fails false.

Currently I have a one big while loop that does the checking and sleeping for 50ms, Which works but I was wondering I there was a better way to do this without any sort of sleep, I tried sleeping 0ms AFAIK this puts my thread to the end of the cpu que but it still utilized way too much cpu around 60%.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜宝宝 2024-12-07 19:26:29

这听起来像是 的用例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 的实例,否则将抛出异常一个ExecutionException(包装执行抛出的异常)。任何一种都会立即发生(感谢执行器完成服务)。

然后你会做出相应的反应:如果f.get()抛出异常,从futures集合中删除f,迭代集合(即通过您提交的其他任务),以及 .cancel() 它们。 Callable 必须被编码为可取消的,否则对 .cancel() 的调用将不会执行任何操作。

This sounds like a use case for 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();

After this, when you call f.get(), you will either get an instance of Result or it will throw an ExectutionException (wrapping the exception thrown by the execution). Either one will happen immediately (thanks to the executor completion service).

Then you will react accordingly: if f.get() throws an exception, remove f from the futures set, iterate through the other elements of the set (that is, through the other tasks you submitted), and .cancel() them. The Callables must be coded to be cancelable, otherwise the call to .cancel() will do nothing.

忆沫 2024-12-07 19:26:29

您可以将 A、B、C 作业包装在一个 Runnable 中,该 Runnable 知道作业何时失败并且还知道控制线程。当此包装器检测到作业失败(异常、运行时条件等)时,它将通知控制线程以采取进一步操作。

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

You can wrap the A, B, C jobs in a Runnable that knows when a job failed and also knows about the controlling thread. When this wrapper it detects that job failed (exception, runtime conditions and what not) it will notify the controlling thread for further action.

That way you will not have to poll the threads but you will wait on a signal from the wrapper error detector.

魂归处 2024-12-07 19:26:29

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

You can add a callback to the jobs, which is invoked in the case that the thread fails. The callback then would proceed to stop all threads.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文