等同于:
AtomicReference<SomeClass> ref = new AtomicReference<SomeClass>( ... );
但没有同步成本。请注意,我做想要将引用包装在另一个对象中。
我查看了扩展 Reference 抽象类的类,但我在所有选择中都有点迷失。
我需要一些非常简单的东西,不是弱的,也不是幻像,也不是除了一个之外的所有其他参考。我应该使用哪个班级?
答案 0 :(得分:5)
如果您想要一个没有线程安全性的引用,您可以使用一个数组。
MyObject[] ref = { new MyObject() };
MyObject mo = ref[0];
ref[0] = n;
答案 1 :(得分:3)
如果您只是想在对象中存储引用。你不能用一个字段创建一个类,考虑到该字段将是一个强大的参考,应该达到你想要的
你不应该创建一个StrongReference类(因为它会很愚蠢),而是要演示它
public class StrongReference{
Object refernece;
public void set(Object ref){
this.reference =ref;
}
public Object get(){
return this.reference;
}
}
答案 2 :(得分:2)
在传统的同步部分意义上,AtomicReference没有同步成本。它被实现为非阻塞,意味着等待&#34;获取锁定的线程&#34;不是上下文切换,这使得它在实践中非常快。可能同时更新单个引用,您找不到更快的方法。
答案 3 :(得分:2)
如果您仍想使用AtomicReference
但又不想承担易失性写入的费用,可以使用lazySet
写入不会发出普通易失性写操作的内存屏障,但是仍然会调用易失性负载(相对便宜)
AtomicReference<SomeClass> ref = new AtomicReference<SomeClass>();
ref.lazySet(someClass);
答案 4 :(得分:2)
我想你想要的只是:
public class MyReference<T>{
T reference;
public void set(T ref){
this.reference =ref;
}
public T get(){
return this.reference;
}
}
您可以考虑添加委托equals(),hashcode()和toString()。
答案 5 :(得分:0)
AtomicReference没有同步成本。来自java.util.concurrent.atomic包的说明:
一个小型工具包,支持对单个变量进行无锁线程安全编程。
修改强>
根据您对原始帖子的评论,您似乎以非标准方式使用术语“同步成本”来表示一般的线程本地缓存刷新。在大多数体系结构中,读取volatile
几乎与读取非易失性值一样便宜。对共享变量的任何更新都将要求缓存刷新至少该变量(除非您要完全取消线程本地缓存)。没有比java.util.concurrent.atomic中的类更便宜(性能方面)。
答案 6 :(得分:0)
所有提供的类扩展Reference附加了一些特殊功能,从原子CaS到允许引用的对象被收集事件thoguh引用仍然存在于对象
您可以创建自己的StringReference,如John Vint所述(或使用长度为== 1的数组)但尽管没有那么多用途
答案 7 :(得分:0)
如果您的价值是不变的,那么java.util.Optional似乎是一个不错的选择。
答案 8 :(得分:0)
从Java 9开始,您现在可以使用AtomicReference.setPlain()
和AtomicReference.getPlain()
。
setPlain
上的JavaDoc:
“将值设置为newValue,并具有设置的内存语义,就好像该变量被声明为非易失性且非最终值一样。”
答案 9 :(得分:0)
使用 java.util.concurrent.atomic.AtomicReference 我也觉得不对,为了共享一个对象的引用.除了“原子性成本”之外,AtomicReference 还充满了与您的用例无关的方法,并且可能会给用户带来错误的期望。 但是我还没有在JDK中遇到过这样的等价类。
以下是您的选择摘要 - 选择最适合您的:
StrongReference
或 MyReference
AtomicReference
中