AtomicReference的语义是什么?
如果我这样做了:
AtomicReference<CustomObject> ref = new AtomicReference<CustomObject>();
然后我做了:
public void someMethod(){
//do something
ref.set(loadNewData());
}
private final Sempahore updatePermit = new Sempahore(1);
private CustomObject loadNewData(){
CustomObject obj = null;
if (updatePermit.tryAcquire()) {
obj = ...; //do the loading and create Object
updatePermit.release();
} else {
//update already running, wait
updatePermit.acquire();
//release the permit immediately
updatePermit.release();
obj = ref.get(); //????
}
return obj;
} 是否有保证在在线obj = ref.get(); //????中get将返回CustomObject的最佳新版本
这与post中的assylias的答案有关。
发布于 2012-11-13 14:32:42
实际上,您的代码有可能导致新数据丢失的争用条件:
ref.get()并获取旧数据。ref.set()的新数据ref.set()时覆盖新数据。由于someMethod()总是加载新数据,并且总是希望调用方在加载新数据时等待,所以所有这些额外的内容都是无用的。只需在整个块周围使用一个简单的同步块(或锁),并丢弃原子引用。根据链接的post,似乎您只想这样做一次,所以使用一个初始化标志。
private boolean _initialized;
public synchronized void loadLatestData() {
if(!_initialized) {
// load latest data ...
_initialized = true;
}
}发布于 2012-11-13 14:29:15
是。
AtomicReference保证发布。
但是,不能保证一个不同的线程不会在一毫秒后设置它。
请注意,如果不调用compareAndSet(),则AtomicReference并不比volatile字段好。
发布于 2012-11-13 14:30:51
读取java.util.concurrent.atomic
get具有读取volatile变量的内存效果。set具有写入(赋值) volatile变量的内存效果。所以保证是:get()总是返回传递给set()的最后一个值。在此期间,您做什么并不重要,您使用什么类型的锁等等。修改volatile变量(实际上是这样做的)可以确保读取该值的所有其他线程都能看到。
https://stackoverflow.com/questions/13362427
复制相似问题