Java arrays: synchronized + Atomic*, or synchroniz

2020-02-14 05:25发布

This question has been asked again and again, but I have still a doubt. When people say that synchronized creates a memory barrier, what does this memory barrier apply to, ANY cached variable? This doesn't look like feasible.

So, due to this doubt, I have written some code that looks like this:

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.

I wonder if it's possible to just substitute the type of total with a plain double[]: this would require that synchronized(total) (in the run() method) assures that I'm not working with local copies of each index in the array of doubles, that is, the memory fence does not apply only to the value of total itself (which is under the hood a pointer), but to the indexes of total too. Does this happen?

2条回答
Luminary・发光体
2楼-- · 2020-02-14 05:34

The memory barrier applies to all memory references, even unrelated ones. When you synchronize total you will see an up to date copy of any memory values and when you leave the block, there is another memory barrier.

查看更多
倾城 Initia
3楼-- · 2020-02-14 05:43

If my understanding is correct synchronized(total) would synchronize any access to total and thus should synchronize access (read and write) to the values in an array, too.

Since a double array directly contains the values instead of references, those should not be accessible by other threads during execution of the synchronized block. If you had an array of objects you would not be able to change the references in the array but you could still access the objects themselves.

查看更多
登录 后发表回答