每次我在非最終類別字段上進行同步時,都會顯示警告。這是代碼:public class X { private Object o; public void setO(Object o) { this.o = o; } public void x() { synchronized (o) // synchronization on a non-final field { } } } 所以我通過以下方式更改了編碼: public class X { private final Object o; public X() { o = new Object(); } public void x() { synchronized (o) { } } } 我不確定上面的代碼是否是在非最終類字段上同步的正確方法。如何同步非最終字段?
3 回答
慕桂英4014372
TA貢獻1871條經驗 獲得超13個贊
首先,我鼓勵您真正嘗試在更高的抽象級別上處理并發問題,即使用java.util.concurrent中的類(例如ExecutorServices,Callables,Futures等)來解決它。
話雖如此,在非最終字段上進行同步本身沒有任何問題。您只需要記住,如果對象引用發生更改,則可以并行運行同一段代碼。即,如果一個線程在同步塊中運行代碼并且有人調用setO(...),則另一個線程可以在同一實例上同時運行同一同步塊。
同步需要獨占訪問的對象(或者,更好的是,專用于保護它的對象)。
瀟湘沐
TA貢獻1816條經驗 獲得超6個贊
這實際上不是一個好主意-因為您的同步塊不再真正以一致的方式進行同步。
假設同步塊旨在確保一次只有一個線程訪問某些共享數據,請考慮:
線程1進入同步塊。是的-它具有對共享數據的獨占訪問權...
線程2調用setO()
線程3(或仍然是2 ...)進入同步塊。ek!它認為它具有對共享數據的獨占訪問權,但是線程1仍在使用它...
您為什么要發生這種情況?也許在某些非常特殊的情況下這是有道理的...但是在您滿意之前,您必須向我介紹一個特定的用例(以及減輕我上面給出的那種情況的方法)它。
添加回答
舉報
0/150
提交
取消
