每次我在非最终类别字段上进行同步时,都会显示警告。这是代码: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
提交
取消