执行程序服务

时间:2015-08-22 13:41:15

标签: java concurrency executorservice happens-before

数组元素是否在工人之间正确发布?

假设我有一个大数组(任何原子数据类型,所以不是longdouble),

  • 我创建了一个填充数组的工作者,我传递给它的构造函数
  • 我将工作人员提交给执行人,并等到完成后(例如future.get())。工人不会退货。它只是填满了我的阵列。
  • 然后,我立即在其构造函数中创建并提交具有相同数组的另一个worker。它看到了最新的价值吗?

换句话说,它确保上次工作的最后一次写入发生在第一次读取下一个工作者之前?

我是否应该(或者为了最佳做法或某事)让第一个工作人员返回数组,即使引用与我已经拥有的引用相同?

[编辑]一些背景:我使用byte数组或short数组,它们代表图像,每个最多使用500,000,000个元素。我对每个元素执行简单的算术运算。

2 个答案:

答案 0 :(得分:3)

来自package java.util.concurrent JavaDoc

  

java.util.concurrent及其子包中所有类的方法将这些保证扩展到更高级别的同步。特别是:

     

由Future表示的异步计算所采取的操作发生在通过另一个线程中的Future.get()检索结果之后的操作之前。

     

在执行Runnable之前,线程中的操作发生在执行开始之前。类似地,提交给ExecutorService的Callables。

根据您的方案中第二个工作人员访问数组似乎非常安全。

答案 1 :(得分:2)

数组的元素不是volatile,因此CPU可能会为每个线程缓存它们。因此,第一个worker可以初始化一些数组元素,但是第二个worker可能因为缓存而没有看到它。

为确保数组元素本身是原子的,您可以使用AtomicReferenceArray