我在实践中阅读并发,有一些误解。
引用:
the real problem with DCL is the assumption that the worst thing that can happen when reading the shared object reference without synchronization is to erroneously see a stale value (in this case, null); in that cse the DCL idiom compensates for this risk by trying again with the lock held. But the worst case is actually considerably wrong - it is possible to see a current value of the reference but stale values for the object's states, meaning that the object could be seen to be in an invalid or incorrect state.
Brian Goetz 写道 DCL 将在当前使用 volatile 的内存模型中工作:
public class DoubleCheckLociing{
private static volatile Resource resource;
public static Resource getInstance(){
if(resource == null){
synchronized(DoubleCheckLociing.class){
if(resource == null){
resource = new Resource();
}
}
}
return resource;
}
}
我不确定关于状态的短语是否理解正确。
让我们想象一下 Resource
类如下所示:
class Resource{
private Date date = new Date();//mutable thread unsafe class
private int k = 10;
public Date getDate(){
return date;
}
public int getK(){
return k;
}
}
我是否可以保证 getInstance
始终返回正确
资源,该资源始终返回正确的k
(10) 和date
?
最佳答案
有了 volatile
,您就可以得到这些保证。如果没有 volatile
,你就不会。
当一个线程写入 volatile 变量resource
时,该操作包含一个“内存屏障”,确保之前写入的所有内容(例如实例字段的初始化)都被写出到系统内存首先。
当另一个线程读取资源
时,它会包含一个内存屏障,确保此后执行的任何读取都不会看到该读取之前从系统内存缓存的值。
这两个内存屏障确保如果线程看到已初始化的资源变量,那么它也将看到该对象中正确初始化的字段。
关于java - 双重检查锁定保证对象的状态 ? (实践中的并发),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42053811/