java - 双重检查锁定保证对象的状态 ? (实践中的并发)

标签 java concurrency double-checked-locking

我在实践中阅读并发,有一些误解。
引用:

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/

相关文章:

python - 并发.futures.ThreadPoolExecutor.map() : timeout not working

c++ - 仅使用 volatile 修复 DCLP

objective-c - 双重检查锁定 - objective-c

java - 在Android中创建JSON ArrayList/JSON对象并发送到PHP

java - 如何使用 Selenium Webdriver 识别特定文本的语言

java - 如何在spring security taglib中不提及hasRole ('ROLE_ADMIN')

c# - 将事务范围添加到 Parallel.Foreach

multithreading - 环形缓冲区,1 个写入器和 N 个读取器

java - JIT如何调度字节码的执行?

java - 如何将 "include"Spring Security配置到应用程序中