JAVA实现单例模式

JAVA实现单例模式主要有:懒汉、饿汉、双重检验锁、静态内部类和枚举几种方式。

一、懒汉,线程不安全

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

 这种方式之所以线程不安全是因为当多个线程同时使用getInstance()方法时,可能产生多个实例。

二、懒汉,线程安全

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

加上synchronized关键字后,保证了线程安全,但是任何时候只能有一个线程调用getInstance()方法,所以并不高效。

三、饿汉

public class Singleton{
    //类加载时就初始化
    private static final Singleton instance = new Singleton();
    
    private Singleton(){}
    public static Singleton getInstance(){
        return instance;
    }
}

 这种方式使得类在装载时就创建了实例。

四、双重检验锁

public class Singleton {
    private volatile static Singleton instance; //声明成 volatile
    private Singleton (){}
    public static Singleton getSingleton() {
        if (instance == null) {                         
            synchronized (Singleton.class) {
                if (instance == null) {       
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
   
}

 这里有两点要注意,一是两次检验instance==null,因为可能有多个线程同时进入外面的if,如果没有内部if检查,会创建多个实例。二是volatile关键字。因为instance=new Singleton()分三步进行:

1) 给instance分配内存;

2)调用Singleton构造函数初始化成员变量;

3)将instance对象指向内存空间。

由于JVM编译器中存在指令排序的优化,也就是说2)和3)的顺序是不能保证的。设想一下,如果执行顺序是1,3,2,在执行完3之后,然后被线程二占用,这时instance已经是非null,线程二直接返回instance,这样在使用时就会报错。

volatile的作用在于禁止指令重排序优化。

五、静态内部类

public class Singleton {  
    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE; 
    }  
}

 这也是一种”懒汉”的方式,把实例化推迟到使用getInstance()方法之后。

六、枚举

public enum EasySingleton{
    INSTANCE;
}

 可见枚举类型是最简单的一种方法。

原文地址:https://www.cnblogs.com/lumouren009/p/4255880.html