在Java中,如果多个线程异步写入基本(双)数组的各个部分,并且(仅)主线程在所有线程完成写入后从数组中读取。
以下示例代码。
非常感谢, 曼努埃尔
//Example code to calculate distance of 1 point to 1mln other points:
double[][] history = this.createRandomMatrix(1000000,8);
double[] order = this.createRandomMatrix(1,8)[0];
double[] result = new double[1000000];
for(int i = 0; i< 100;i++){
pool.execute(new Calculator(history, newPoint, result,i*10000,10000 + i * 10000));
}
pool.shutdown();
try {
pool.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//read happens here
//Calculator run function
public void run() {
for(int i = start;i<end;i++){
result[i] = this.computeDistance(history[i],order);
}
}
答案 0 :(得分:1)
由于它是一个你正在讨论的数组(静态数组),除非intentionally created,否则不会创建线程本地版本。每个块将读/写同一存储块(阵列的存储块)中的地址。由于写入是对阵列的单独部分进行的,因此不会发生data races。由于您说在完成其他线程的写入后由主线程完成读取,因此不需要同步。
答案 1 :(得分:0)
存在可见性问题。这并不意味着每个线程都有它的本地副本。它只是意味着不能保证主线程可以看到其他线程写的值。
我没有试图设置内存障碍(我无法提出同步所有对result
数组的访问背后的任何想法,这可能会破坏多个线程的整个目的),我建议提交Callable
你的遗嘱执行人:
List<Future> futures = ExecutorService#invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>)
然后每个线程都可以返回自己的结果,主线程将使用它们并获得最终结果。无需共享状态result
。