java – 可变原子参考是一个坏主意吗?
作者:互联网
我有一个我偶尔希望修改的数据结构,偶尔也希望直接替换.目前,我将其存储在AtomicReference中,并在我需要修改它时使用同步块(在AtomicReference本身上同步,而不是其存储的值),而不是替换它.
所以类似于:
public void foo(AtomicReference reference){
synchronized(reference){
reference.get()
.performSomeModification();
}
}
请注意,修改调用是包装值的成员,而不是原子引用,并且不保证它具有自己的任何线程安全性.
这样安全吗? Findbugs(一个免费软件代码审查工具)有this可以说它,所以现在我担心发生在引擎盖下的事情,它可能过早地释放锁或什么.我还看到了引用AtomicReference的文档,专门用于不可变的事情.
这样安全吗?如果不是,我可以创建自己的参考存储类,我会更加确定行为,但我不想妄下结论.
解决方法:
从链接的文档:
For example, synchronizing on an
AtomicBoolean
will not prevent other threads from modifying theAtomicBoolean
.
它无法阻止其他线程修改AtomicBoolean,因为它无法强制其他线程在AtomicBoolean上进行同步.
如果我正确理解您的问题,您的目的是同步调用performSomeModification().当且仅当每个对performSomeModification()的调用在同一对象上同步时,您编写的代码才能实现.如文档中的示例所示,基本问题是该要求的可执行性.您无法强制其他调用方在AtomicReference上进行同步.您或其他开发人员可以轻松调用performSomeModification()而无需外部同步.
您应该很难错误地使用您的API.由于AtomicReference是泛型类型(AtomicReference< V>),因此您可以通过多种方式强制执行同步,具体取决于V:
>如果V是一个接口,您可以轻松地将实例包装在同步包装器中.
>如果V是可以修改的类,则可以同步performSomeModification(),或创建一个同步它的子类. (可能是工厂方法生成的匿名子类.)
>如果V是一个无法修改的类,则可能很难换行.在这种情况下,您可以将AtomicReference封装在您控制的类中,并让该类执行所需的同步.
标签:java,multithreading,synchronized,atomicreference 来源: https://codeday.me/bug/20190828/1756263.html