相当于 AtomicReference,但没有不稳定的同步成本

问题描述 投票:0回答:10

相当于什么:

AtomicReference<SomeClass> ref = new AtomicReference<SomeClass>( ... );

但没有同步成本。 请注意,我确实想将引用包装在另一个对象中。

我查看了扩展 Reference 抽象类的类,但我在所有选择中有点迷失。

我需要一些非常简单的东西,既不是弱的,也不是幻影,也不是除一个之外的所有其他参考资料。 我应该使用哪个类?

java reference
10个回答
9
投票

如果您想要一个没有线程安全的引用,您可以使用一个数组。

MyObject[] ref = { new MyObject() };
MyObject mo = ref[0];
ref[0] = n;

6
投票

使用 java.util.concurrent.atomic.Atomic为了共享对象的引用,引用对我来说也是错误的。除了“原子性成本”之外,AtomicReference 还充满了与您的用例无关的方法,并且可能会给用户带来错误的期望。 但我在JDK中还没有遇到这样的等价类。

以下是您的选择摘要 - 选择最适合您的:

  • 一个自写的值容器,例如其他答案中提出的
    StrongReference
    MyReference
  • MutableObject 来自 Apache Commons Lang
  • 长度 == 1 的数组或大小 == 1 的 List 自 Java 9 起,
  • setPlain(V)getPlain() 中的 AtomicReference
    
    
编辑:

Kotlin 支持

闭包

,编译器只需使用捕获容器的单个公共字段。 所以一个非常直接的实现是: public static final class Box<T> { public T value; }



4
投票

您不应该创建 StrongReference 类(因为它很愚蠢),而是为了演示它

public class StrongReference{ Object refernece; public void set(Object ref){ this.reference =ref; } public Object get(){ return this.reference; } }



4
投票
AtomicReference.setPlain()

AtomicReference.getPlain()

JavaDoc 上

setPlain

: “将值设置为 newValue,设置的内存语义就好像该变量被声明为非易失性和非最终的。”

    


2
投票


2
投票
AtomicReference

但又不想承担易失性写入的成本,您可以使用

lazySet

写入不会像普通的易失性写入那样产生内存屏障,但获取仍然会调用易失性加载(相对便宜)

AtomicReference<SomeClass> ref = new AtomicReference<SomeClass>(); ref.lazySet(someClass);



2
投票

public class MyReference<T>{ T reference; public void set(T ref){ this.reference =ref; } public T get(){ return this.reference; } }

您可以考虑添加委托 equals()、hashcode() 和 toString()。


0
投票

您可以创建自己的 StringReference,如

John Vint

所解释的那样(或使用长度==1的数组),但没有那么多用途


0
投票
java.util.concurrent.atomic

包的描述:

支持单变量无锁线程安全编程的小型类工具包。

编辑

根据您对原始帖子的评论,您似乎以非标准方式使用术语“同步成本”来表示一般线程本地缓存刷新。在大多数架构上,读取 volatile 几乎与读取非易失性值一样便宜。对共享变量的任何更新都需要至少刷新该变量的缓存(除非您要完全废除线程本地缓存)。没有什么比 java.util.concurrent.atomic 中的类更便宜(性能方面)的了。

    


0
投票
java.util.Optional

看起来是一个不错的选择。

© www.soinside.com 2019 - 2024. All rights reserved.