为了账号安全,请及时绑定邮箱和手机立即绑定

非最终字段的同步

非最终字段的同步

哔哔one 2019-11-27 09:58:51
每次我在非最终类别字段上进行同步时,都会显示警告。这是代码: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(...),则另一个线程可以在同一实例上同时运行同一同步块。


同步需要独占访问的对象(或者,更好的是,专用于保护它的对象)。


查看完整回答
反对 回复 2019-11-27
?
潇湘沐

TA贡献1816条经验 获得超6个赞

这实际上不是一个好主意-因为您的同步块不再真正以一致的方式进行同步。

假设同步块旨在确保一次只有一个线程访问某些共享数据,请考虑:

  • 线程1进入同步块。是的-它具有对共享数据的独占访问权...

  • 线程2调用setO()

  • 线程3(或仍然是2 ...)进入同步块。ek!它认为它具有对共享数据的独占访问权,但是线程1仍在使用它...

您为什么发生这种情况?也许在某些非常特殊的情况下这是有道理的...但是在您满意之前,您必须向我介绍一个特定的用例(以及减轻我上面给出的那种情况的方法)它。


查看完整回答
反对 回复 2019-11-27
  • 3 回答
  • 0 关注
  • 706 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信