這個問題一再被問到,但我仍然有疑問。當人們說同步創建內存屏障時,這個內存屏障應用於什麼,任何緩存變量?這看起來不太可行。Java數組:同步+原子*,或同步足夠?
因此,由於這個疑問,我已經寫了一些代碼,看起來像這樣:
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.
我不知道是否有可能剛剛替補總的類型有普通的雙[]:這將需要同步(總)(在run()方法中)確保我沒有使用雙精度數組中每個索引的本地副本,也就是說,內存圍欄不僅適用於total
本身的值在引擎蓋下是一個指針),但也指向total
。這是否發生?
謝謝,這真是我需要的答案。可惜這是我的第一個問題,所以我還沒有投票。 –
當你提到「*不相關的* ones」時,你的意思是**在synchronized塊中的變量(但與* total *無關),對吧?即你並不是指與全局無關的那些(即與* total *無關並且與* total *用於同步,但被緩存並且在主存儲器中具有過時值的塊)無關。換句話說,你並不是指整個過程的所有緩存變量? (我知道這可能是一個愚蠢的問題,但只是爲了確保......)。 –
synchronized使用一個內存屏障來確保所有內存處於該線程的一致狀態,無論該內存是否在該塊內被引用。 –