Этот вопрос задавался снова и снова, но у меня все еще есть сомнения. Когда люди говорят, что synchronized создает барьер памяти, к чему относится этот барьер памяти, к ЛЮБОЙ кешированной переменной? Это не выглядит возможным.
Итак, из-за этого сомнения я написал код, который выглядит следующим образом:
final AtomicReferenceArray<Double> total=new AtomicReferenceArray<Double>(func.outDim);
for(int i=0; i<func.outDim; i++) total.set(i, 0.);
for(int i=0; i<threads; i++){
workers[i]=new Thread(new Runnable(){
public void run() {
double[] myPartialSum=new double(func.outDim);
//some lengthy math which fills myPartialSum...
//The Atomic* guarantees that I'm not writing local copies of the Double references (whose value are immutables, so it's like an array of truly volatile doubles) in variable total, synchronized(total) atomizes the sum
synchronized(total){ for(int i=0; i<func.outDim; i++) total.set(i, total.get(i)+myPartialSum[i]); }
};
workers[i].start();
}
//wait for workers to terminate...
//print results accessing total outside of a synchronized(total) block, since no worker is alive at this point.
Интересно, можно ли просто заменить тип итога простым двойным []: для этого потребуется, чтобы synchronized (total) (в методе run ()) гарантировал, что я не работаю с локальными копиями Индекс в массиве double, то есть ограничение памяти применяется не только к значению total
(которое находится под указателем), но и к индексам total
. Это происходит?