在invokeAll之后执行器任务的所有副作用都可见吗?

发布于 2024-12-05 01:23:13 字数 397 浏览 5 评论 0原文

如果我使用 invokeAllExecutor 提交一些任务,我能否保证提交的线程看到任务执行的所有副作用,即使我不调用 < code>get() 在每个返回的 Future 上?

从实际的角度来看,这似乎是一个有用的保证,但我在 javadoc 中没有看到任何内容。

更准确地说,提交给执行程序的 Callable 主体中的所有操作是否都发生在 invokeAll() 调用返回之前?

在每个 future 上无用地调用 get() 是很烦人的,而实际上返回类型是 Void 并且没有抛出异常 - 所有的工作都是作为副作用发生的。

If I submit some tasks to an Executor using invokeAll, am I guaranteed that the submitted thread sees all the side effects of the task executions, even if I don't call get() on each of the returned Futures?

From a practical point of view, it would seem that this would be a useful guarantee, but I don't see anything in the javadoc.

More precisely, do all actions in the body of a Callable submitted to an executor happen-before the return from the invokeAll() call?

It's annoying to uselessly call get() on each future, when in fact the return type is Void and no exceptions are thrown - all the work in the happens as side-effects.

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

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

发布评论

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

评论(2

森罗 2024-12-12 01:23:13

ExecutorService 的文档:

提交 Runnable 或 Callable 之前线程中的操作
ExecutorService 的任务发生在执行任何操作之前
任务,这又发生在通过检索结果之前
Future.get()。

当我读到这篇文章时,任务提交存在内存障碍,因此可能您需要对列表中的最后一个任务调用get(),但不需要其他人。

但是,由于调用 get() 是确定任务是否完成或抛出的唯一方法,我仍然会在每个 Future 上调用它,无论内存保证如何。

From the documentation of ExecutorService:

Actions in a thread prior to the submission of a Runnable or Callable
task to an ExecutorService happen-before any actions taken by that
task, which in turn happen-before the result is retrieved via
Future.get().

As I read this, there is a memory barrier on task submission, so potentially you'd need to call get() on the last task in your list to, but not the others.

However, since calling get() is the only way to determine whether the task completed or threw, I would still call it on every Future, regardless of memory guarantees.

木緿 2024-12-12 01:23:13

如果 invokeAny() 承诺当 invokeAny() 返回时没有任务仍在执行,那么情况就是这样:所有副作用都是可见的。

为了让 invokeAny() 知道所有任务都已完成,它需要与这些线程同步,这意味着函数的返回发生在任务完成之后(以及任务中发生的所有事情) )。然而,“ExecutorSerive”和“Future.cancel()”的 API 并没有明确说明取消正在运行的任务时会发生什么(特别是:将 cancel() 等待返回,直到任务停止事实上,在调用 cancel() 后,isDone() 必须返回 true,这确实意味着 cancel() 不会返回,直到任务实际上已经完成 。

另一件需要注意的事情是,在使用 invokeAny() 时,如果不检查 Future 对象,您将不知道任务是否已开始执行

If invokeAny() promises that no tasks are still in execution when invokeAny() returns, this will be the case: all side effects are visible.

In order for invokeAny() to know that all tasks are done, it needs to have synchronized with those threads, meaning that the returning of the functions happens after the tasks completing (and everything that happens in the task). However the API of 'ExecutorSerive' and 'Future.cancel()' does not explicitly say what happens when you cancel a running task (in particular: will cancel() wait with returning until the tasks has stopped running. The fact that after calling cancel(), isDone() must return true, does imply that cancel() will not return until the task has actually finished executing.

One more thing to watch out for is that you will not know if a task ever started execution, when using invokeAny() without inspecting the Future objects.

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