编程语言
首页 > 编程语言> > java – 可变原子参考是一个坏主意吗?

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 the AtomicBoolean.

它无法阻止其他线程修改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