`
guiven
  • 浏览: 28924 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

单例模式(double checked locking+静态工厂+枚举)

 
阅读更多

double checked locking 实现法:

下面代码就是用double checked locking 方法实现的单例,这里的getInstance()方法要检查两次,确保是否实例INSTANCE是否为null或者已经实例化了,这也是为什么叫double checked locking 模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Singleton pattern example with Double checked Locking
*/
public class DoubleCheckedLockingSingleton{
     private volatile DoubleCheckedLockingSingleton INSTANCE;
 
     private DoubleCheckedLockingSingleton(){}
 
     public DoubleCheckedLockingSingleton getInstance(){
         if(INSTANCE == null){
            synchronized(DoubleCheckedLockingSingleton.class){
                //double checking Singleton instance
                if(INSTANCE == null){
                    INSTANCE = new DoubleCheckedLockingSingleton();
                }
            }
         }
         return INSTANCE;
     }
}

你可以使用 DoubleCheckedLockingSingleton.getInstance()来获取实例。

 

从创建一个lazy loaded thread-safe单例来看,它的代码行数与枚举相比,后者可以全部在一行内完成,因为枚举创建的单例在JVM层面上也能保证实例是thread-safe的。

 

静态工厂实现法:

这是我最喜欢的一种方式来实现单例模式,因为单例是静态的final变量,当类第一次加载到内存中的时候就初始化了,所以创建的实例固然是thread-safe。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* Singleton pattern example with static factory method
*/
 
public class Singleton{
    //initailzed during class loading
    private static final Singleton INSTANCE = new Singleton();
 
    //to prevent creating another instance of Singleton
    private Singleton(){}
 
    public static Singleton getSingleton(){
        return INSTANCE;
    }
}

你可以调用Singleton.getSingleton()获取实例。这种非延迟加载,而是在启动时就加载好。

 

另外一个值得注意的点就是,传统单例存在的另外一个问题是一旦你实现了序列化接口,那么它们不再保持单例了,因为readObject()方法一直返回一个新的对象就像java的构造方法一样,你可以通过使用readResolve()方法来避免此事发生,看下面的例子:

1
2
3
4
//readResolve to prevent another instance of Singleton
    private Object readResolve(){
        return INSTANCE;
    }

这样甚至还可以更复杂,如果你的单例类维持了其他对象的状态的话,因此你需要使他们成为transient的对象。但是枚举单例,JVM对序列化有保证。

关于readResolve()方法跟readObject()方法可以参见:

http://stackoverflow.com/questions/1168348/java-serialization-readobject-vs-readresolve

我对此的理解就是ReadObject方法会新生成一个新的实例,readResolve方法执行在readObject方法之后,用于替换生成的实例(与此对应的是writeReplace方法在writeObject方法之前),而当实现了该方法以后可以保证序列化后的唯一

分享到:
评论

相关推荐

    单例模式和工厂模式代码

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

    设计模式——单例模式

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

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

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

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

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

    单例模式(singleton)

    这通常通过私有化构造函数和提供一个公共静态方法(称为单例工厂方法)来实现。在Java中,单例模式的实现有多种方式: 1. 饿汉式(Static Singleton):在类加载时就创建了唯一实例,线程安全,但可能会造成资源...

    Java实现多种单例模式

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

    C#版本的单例模式源码

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

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

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

    设计模式_创建型_单例模式.md

    ### 双重检查锁定(Double-Checked Locking) 双重检查锁定是懒汉式单例的一种实现方式,它在懒汉式单例的基础上增加了双重检查锁定,确保只实例化一次。在单例类中增加了一个静态私有变量用于保存类的唯一实例,...

    Singleton 单例模式的介绍以及解析

    2. **双重检查锁定(DCL,Double-Checked Locking)**:这是一种优化的懒汉式实现,通过添加volatile关键字和synchronized关键字来保证线程安全。在多线程环境下,只有一个线程能执行初始化操作,其他线程会等待初始...

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

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

    线程相关的单例模式

    为了解决这个问题,可以使用双重检查锁定(Double-Checked Locking,DCL)机制,它在保证线程安全的同时,尽可能地减少了同步的开销。DCL的核心思想是在实例化对象之前先检查实例是否已经被创建,只有在未被创建的...

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

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

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

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

    深入浅出单例Singleton模式

    在这个版本中,我们进行了双重检查锁定(Double-Checked Locking),先检查`singleton`是否为空,如果为空才进行同步操作。这种优化减少了同步的开销,但仍然保证了线程安全。 4. **静态内部类**: ```java ...

    java:单例模式 作为对象的创建模式

    为了解决这个问题,可以采用双检锁/双重校验锁定(Double-Checked Locking)模式,既保证了线程安全,又延迟了实例化,提高性能: ```java class DanLi{ private volatile static DanLi obj; private DanLi(){} ...

    java 单例模式

    2. 另一种常见的实现方式是双重检查锁定(double-checked locking)模式,它在保证线程安全的同时也尽可能减少了同步开销: ```java public class SingletonClass { private volatile static SingletonClass ...

    单例模式的介绍(含程序代码)

    if (uniqueInstance == null) { // 双重检查锁定(Double-Checked Locking) synchronized (LazySingleton.class) { if (uniqueInstance == null) { uniqueInstance = new LazySingleton(); } } } return ...

Global site tag (gtag.js) - Google Analytics