我有一个简单的关于AtomicReference的一般问题.
为什么使用AtomicReference,如果引用赋值在java中是原子的?
另外我想问一下64位虚拟机中的引用分配是否是原子的?
我们是否需要挥发性以使参考分配原子?
我只是碰到了一篇文章,这篇文章提出了我以前从未听过的声明,但在其他任何地方都找不到.声明是从另一个线程的角度来看,构造函数返回的值的赋值可以相对于构造函数内的指令重新排序.换句话说,声明是在下面的代码中,另一个线程可以读取尚未设置a值的非空值x.
class MyInt {
private int x;
public MyInt(int value) {
x = value;
}
public int getValue() {
return x;
}
}
MyInt a = new MyInt(42);
Run Code Online (Sandbox Code Playgroud)
这是真的?
编辑:
我认为从线程执行的角度来看,保证MyInt a = new MyInt(42)了赋值与赋值的x发生关系a.但是这两个值都可以缓存在寄存器中,并且它们可能不会按照它们最初写入的顺序刷新到主存储器.没有内存屏障,另一个线程因此可以在写入值a之前读取值x.正确?
因此,基于axtavt的答案和随后的评论,这些线程安全评估是否正确?
// thread-safe
class Foo() {
final int[] x;
public Foo() {
int[] tmp = new int[1];
tmp[0] = 42;
x = tmp; // memory …Run Code Online (Sandbox Code Playgroud) 如果我在多线程环境中有一个不同步的java集合,并且我不想强制集合的读者同步[1],那么我是一个同步编写器并使用引用赋值的原子性可行的解决方案吗?就像是:
private Collection global = new HashSet(); // start threading after this
void allUpdatesGoThroughHere(Object exampleOperand) {
// My hypothesis is that this prevents operations in the block being re-ordered
synchronized(global) {
Collection copy = new HashSet(global);
copy.remove(exampleOperand);
// Given my hypothesis, we should have a fully constructed object here. So a
// reader will either get the old or the new Collection, but never an
// inconsistent one.
global = copy;
}
}
// Do multithreaded reads here. …Run Code Online (Sandbox Code Playgroud)