我對同步塊有一些懷疑。 在我的問題之前,我想分享來自其他相關職位Link for Answer to related question的答案。我從同一個答案引用Peter Lawrey。如果我們正在同步讀取,我們是否需要同步寫入?
-
同步,確保您擁有的數據的一致視圖。這意味着您將讀取最新值,而其他緩存將獲得最新值 。高速緩存足夠聰明,可以通過 特殊總線(不是JLS所要求的但允許)相互通信。總線意味着它不必觸碰主存以獲得一致的視圖。
-
如果您只使用同步,您將不需要易失性。如果你有一個非常簡單的操作,同步的 會過度揮發,揮發性是有用的。
在參照上述我有以下三個問題:
Q1。假設在一個多線程應用程序中,只有一個對象或一個原始實例字段只能在一個同步塊中讀取(寫入操作可能會發生在沒有同步的其他方法中)。同步塊也在其他對象上定義。 是否聲明它是不穩定的(即使它只在同步塊內讀取)有意義? Q2302。 我瞭解同步已完成的對象的狀態值是一致的。我不確定其他對象和原始字段在Synchronized塊的讀取狀態。 假設在沒有獲得鎖的情況下進行更改,但通過獲取鎖來完成讀取。 Alwaysized塊中的所有對象和所有原始字段的值的狀態都始終具有一致的視圖。?
Q3。 [更新]:無論我們鎖定什麼內容,是否將從主內存中讀取正在同步塊中讀取的所有字段? [由CKing回答]
我有一個參考編碼,用於解決上述問題。
public class Test {
private SomeClass someObj;
private boolean isSomeFlag;
private Object lock = new Object();
public SomeClass getObject() {
return someObj;
}
public void setObject(SomeClass someObj) {
this.someObj = someObj;
}
public void executeSomeProcess(){
//some process...
}
// synchronized block is on a private someObj lock.
// inside the lock method does the value of isSomeFlag and state of someObj remain consistent?
public void someMethod(){
synchronized (lock) {
while(isSomeFlag){
executeSomeProcess();
}
if(someObj.isLogicToBePerformed()){
someObj.performSomeLogic();
}
}
}
// this is method without synchronization.
public void setSomeFlag(boolean isSomeFlag) {
this.isSomeFlag = isSomeFlag;
}
}
我想對此很好,但那是其中一個最誠實的工作方式。如果你在談論JMM時想到的是「從內存中獲取」的東西,那麼你還沒有明白它,應該遠離併發。但是沒有給出的代碼是不正確的。 – Voo
使'isSomeFlag'揮發性將解決此問題 – ControlAltDel
@Voo我編輯了我的問題,抱歉使用單詞記憶,我的意思是一致的.. –