`

double-checked locking实现的单例模式之volatile

阅读更多
private volatile static Singleton instance;

public static Singleton getInstance() {
    if (instance == null) {
        synchronized(Singleton.class) {  //1
            if (instance == null)          //2
                instance = new Singleton();  //3
        }
    }
    return instance;
}
 

看这个double-checked locking单例模式的实现,volatile关键字使用的必要性在哪里?想这问题之前,可以预读这篇文章:

http://www.ibm.com/developerworks/java/library/j-dcl.html

 

 

因为存在Out-of-order writes现象,所以这里volatile关键字是在当instance被初始化给Singleton实例时保证多线程正确地处理instance变量,那这里与线程间的可见性有关吗?

 

回答:

我觉得与可见性无关,因为synchronized block已经可以保证块内变量的可见性,这里应该是变量操作的原子性

 

For references and all primitives (except sometimes long ), two threads will always see a complete value, never one half-way modified by another thread. The official term for such an intact atomic value is a consistent value .

 

http://mindprod.com/jgloss/volatile.html

 

2010.05.28 补充:

阅此文:

http://www.ibm.com/developerworks/java/library/j-jtp06197.html

 

其中有说到:

Pattern #2: one-time safe publication
The visibility failures that are possible in the absence of synchronization can get even trickier to reason about when writing to object references instead of primitive values. In the absence of synchronization, it is possible to see an up-to-date value for an object reference that was written by another thread and still see stale values for that object's state. (This hazard is the root of the problem with the infamous double-checked-locking idiom, where an object reference is read without synchronization, and the risk is that you could see an up-to-date reference but still observe a partially constructed object through that reference.)

One technique for safely publishing an object is to make the object reference volatile. Listing 3 shows an example where during startup, a background thread loads some data from a database. Other code, when it might be able to make use of this data, checks to see if it has been published before trying to use it.


volatile在引用是最新,但对象状态是陈旧的状况下可以起到作用,保证都是最新。

 

 

 

 

2011.02.10 补充更新:

http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

这篇文章很不错,火龙果提供链接

 

 

 

分享到:
评论

相关推荐

    C++ and the Perils of Double Checked Locking.zip

    《C++ and the Perils of Double Checked Locking》是一篇探讨C++编程中双重检查锁定(Double-Checked Locking)模式潜在问题的文献。在多线程编程中,双重检查锁定是一种常见的优化策略,旨在减少对同步原语的依赖...

    Java-设计模式-单例模式-实现源码(简单实现、双重检查锁、静态内部类、枚举类)

    在Java中,有多种实现单例模式的方法,包括简单实现、双重检查锁定(Double-Checked Locking)、静态内部类和枚举类。下面我们将详细探讨这些不同的实现方式。 1. **简单实现(非线程安全)** 最简单的单例实现...

    单例模式详解~~单例模式详解~~

    为了解决这个问题,我们可以采用"双检锁/双重校验锁"(DCL,即Double-Checked Locking)的策略,这是一种优化过的懒汉式单例。DCL模式在Java中如下所示: ```java public class SingletonKerriganB { private ...

    C#设计模式学习与演变过程-2-单例模式

    3. **双检单例(Double-Checked Locking)**: 双检锁模式试图在保证线程安全的同时减少不必要的同步开销。其核心思想是只有在实例为空时才进行同步操作: ```csharp public class Singleton { private static ...

    Java实现多种单例模式

    3. 双重校验锁(Double-Checked Locking): 这种方式结合了懒汉式的延迟初始化和饿汉式的线程安全性。`SingleInstance3.java`可能使用了这种模式。它在多线程环境下是安全的,但比饿汉式稍微复杂一些,因为需要...

    使用单例模式创建学生管理系统(饿汉式、懒汉式)

    但是,如果不进行同步控制,懒汉式在多线程环境下可能会创建多个实例,因此通常采用双重检查锁定(Double-Checked Locking,DCL)来实现线程安全的懒汉式单例: ```java public class Singleton { private ...

    设计模式——单例模式

    1. **双检锁/双重校验锁(DCL,即 double-checked locking)** ```java public class Singleton { private volatile static Singleton instance; private Singleton() {} public static Singleton getInstance...

    单例模式讲解说明与实例

    另一个解决方案是使用双重检查锁定机制(Double-Checked Locking)来实现线程安全的单例模式。这种方法可以减少 synchronize 的使用,从而提高系统的性能。 ```java public class Singleton { private volatile ...

    单例模式(singleton)

    3. 双重检查锁定(Double-Checked Locking):结合了前两者,延迟初始化并保证线程安全。 ```java public class Singleton { private volatile static Singleton instance; private Singleton() {} public static...

    设计模式单例模式

    懒汉式的常见实现是使用双重检查锁定(Double-Checked Locking,DCL): ```java public class Singleton { private volatile static Singleton instance; private Singleton() {} public static Singleton ...

    340.338.JAVA基础教程_面向对象(下)-复习:单例模式(340).rar

    3. 双重检查锁定(Double-Checked Locking):结合了前两者的优势,既延迟初始化又保证线程安全。这种方式在Java 5及以上版本中是安全的,因为它依赖于 volatile 关键字来确保可见性和有序性。 ```java public ...

    C#版本的单例模式源码

    2. **双检锁/双重校验锁定(Double-Checked Locking,DCL)** 这种方法在早期的.NET框架中被广泛使用,但后来由于.NET内存模型的变化,其线程安全性变得复杂。在.NET 4.0及更高版本中,可以安全地使用此方法: ``...

    单例模式和工厂模式代码

    // 双检锁/双重校验锁(DCL,即 double-checked locking) public class Singleton { private volatile static Singleton instance; private Singleton() {} public static Singleton getInstance() { if ...

    java单例模式完全剖析

    为了解决这个问题,可以使用“双检锁/双重校验锁”(Double-Checked Locking)策略: ```java public class ThreadSafeSingleton { private volatile static ThreadSafeSingleton instance; private ...

    设计模式实现——单例模式

    但同步操作会影响性能,因此有更高效的方法,如双检锁/双重校验锁定(DCL,Double-Checked Locking): ```java public class Singleton { private volatile static Singleton instance; private Singleton() ...

    Java双重检查加锁单例模式的详解

    DCL(Double-checked locking)是Java双重检查加锁单例模式的一种实现方法。它使用了synchronized关键字来确保线程安全,但是这也会带来性能损失。DCL看起来是一个聪明的优化,但是它却不能保证正常工作。 在多线程...

    2 单例模式-MOOC课程内容.pdf

    为了保证线程安全,可以使用双重检查锁定模式(Double-Checked Locking Pattern),确保只有一个实例被创建。但是这要求必须使用关键字volatile修饰静态实例变量,以防止指令重排序导致的问题。单例模式1和单例模式2...

    设计模式java实现之单例模式1

    4. **线程安全旗舰版 - 双重检查锁定(DCL,Double-Checked Locking)**: DCL模式结合了延迟加载和线程安全,它在初始化实例时使用双重检查,避免了无谓的同步开销。`volatile`关键字确保了`uniqueInstance`的可见...

    01 设计模式之单例模式.pdf

    3. 双重检查锁定(Double-Checked Locking) 双重检查锁定是一种优化懒汉式单例模式的写法,它可以在多线程环境中保证实例的唯一性,同时避免不必要的同步开销。通过在声明实例变量时加上volatile关键字,可以确保在...

    JAVA单例模式应用研究

    #### 五、双重检查锁定(Double-Checked Locking)单例模式 为了解决懒汉式单例模式在多线程环境下的性能问题,可以采用双重检查锁定策略。这种方法只在必要时进行同步,提高了效率。 ```java public class ...

Global site tag (gtag.js) - Google Analytics