非最终字段的同步

每次我在非最终类别字段上进行同步时,都会显示警告。这是代码:


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)

     {  

     }  

   }  

 }  

我不确定上面的代码是否是在非最终类字段上同步的正确方法。如何同步非最终字段?


哔哔one
浏览 710回答 3
3回答

慕桂英4014372

首先,我鼓励您真正尝试在更高的抽象级别上处理并发问题,即使用java.util.concurrent中的类(例如ExecutorServices,Callables,Futures等)来解决它。话虽如此,在非最终字段上进行同步本身没有任何问题。您只需要记住,如果对象引用发生更改,则可以并行运行同一段代码。即,如果一个线程在同步块中运行代码并且有人调用setO(...),则另一个线程可以在同一实例上同时运行同一同步块。同步需要独占访问的对象(或者,更好的是,专用于保护它的对象)。

潇湘沐

这实际上不是一个好主意-因为您的同步块不再真正以一致的方式进行同步。假设同步块旨在确保一次只有一个线程访问某些共享数据,请考虑:线程1进入同步块。是的-它具有对共享数据的独占访问权...线程2调用setO()线程3(或仍然是2 ...)进入同步块。ek!它认为它具有对共享数据的独占访问权,但是线程1仍在使用它...您为什么要发生这种情况?也许在某些非常特殊的情况下这是有道理的...但是在您满意之前,您必须向我介绍一个特定的用例(以及减轻我上面给出的那种情况的方法)它。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java