[设计模式]单件模式

1、定义:单件模式确保一个类只有一个实例,并提供一个全局访问点。

2、实现方式:

  • 经典方式:
public class Singleton{
    private static Singleton uniqueInstance;

    private Singleton(){}
        public static Singleton getInstance(){
            if(uniqueInstance == null){
                uniqueInstance = new Singleton();
            }
            return uniqueInstance;
    }
}

经典方式的缺陷是如果多线程同时使用,可能会导致创建了多个实例,违反了单件模式的意义,为了解决多线程灾难问题,可以加同步关键字,如下程序所示。

  • 多线程方法(同步:该方法保证每个线程在进入方法前,要先等候别的线程离开该方法才可以。即不会有两个线程同时进入这个方法):
public class Singleton{
    private static Singleton uniqueInstance;

    private Singleton(){}
        public static synchronized Singleton getInstance(){
            if(uniqueInstance == null){
                uniqueInstance = new Singleton();
            }
            return uniqueInstance;
    }
}

该方法虽然解决了多线程灾难问题,但是又会出现性能问题,因为只有在第一次创建单例对象时需要同步,之后每一次调用该方法都会使用同步,但是这个时候就会造成多线程等待当前线程调用的情况,也就是性能问题。如果说不需要考虑性能问题的话,可以直接使用该方法,这是最好的,但是如果说,真的需要解决多线程灾难且不能引起性能问题,可以采用如下两种方法。

  • 线程安全:
public class Singleton{
    private static Singleton uniqueInstance = new Singleton();

    private Singleton(){}
        public static synchronized Singleton getInstance(){
            return uniqueInstance;
    }
}

该方法方法是在静态初始化器中创建单件,这保证了线程安全。

  • 双重检查加锁:
public class Singleton{
    private volatile static Singleton uniqueInstance;

    private Singleton(){}
        public static synchronized Singleton getInstance(){
            if(uniqueInstance == null){
                synchronized (Singleton.class){
                    if(uniqueInstance == null){
                        uniqueInstance = new Singleton();
                    }
                }              
            }
            return uniqueInstance;
    }
}

该方法保证首先检查实例是否已经创建了,如果尚未创建,才进行同步,否则直接使用已创建实例即可。这个方法既保证了线程安全又保证了性能问题。

volatile关键词确保:当uniqueInstance变量被初始化城Singleton实例时,多个线程正确地处理uniqueInstance变量。

参考资料

[1] head first 设计模式

原文地址:https://www.cnblogs.com/mj-selina/p/12489677.html