在invokeAll之后,执行程序任务的所有副作用是否都可见?

时间:2011-09-14 07:47:50

标签: java multithreading concurrency java.util.concurrent memory-model

如果我使用ExecutorinvokeAll提交某些任务,我保证提交的线程会看到任务执行的所有副作用,即使我没有调用{{1}在每个返回的get() s?

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

更准确地说,提交给执行者Future正文中的所有操作都是在Callable来电之前发生的吗?

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

2 个答案:

答案 0 :(得分:1)

如果invokeAny()承诺在invokeAny()返回时没有任务仍在执行中,则会出现这种情况:所有副作用都是可见的。

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

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

答案 1 :(得分:1)

来自ExecutorService的文档:

  

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

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

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