【JAVA】设计模式 单例模式的五种代码

单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。

懒汉模式(线程不安全方式 不推荐 新手一般会这么写)

/**
 * 懒汉模式
 * 单例实例在第一次使用时被创建 容易出bug 线程不安全的
 */
public class SingletonExample {
    //私有构造对象
    private  SingletonExample(){

    }
    //单例对象
    private  static  SingletonExample instance = null;
    //静态工厂方法
    public  static  SingletonExample getInstance(){
        if(instance == null){
            instance = new SingletonExample();
        }
        //这种方法 == null 在单线程下没什么问题,多线程下容易出现问题,因为可能同时有两个以上的线程走到if里
        return  instance;
    }
}

懒汉模式(线程安全方式,加synchronized 不推荐)

/**
 * 懒汉模式
 * 单例实例在第一次使用时被创建  加了synchronized有开销
 */
@ThreadSafe
public class SingletonExample3 {
    //私有构造对象
    private SingletonExample3(){

    }
    //单例对象
    private  static SingletonExample3 instance = null;
    //静态工厂方法  有性能开销
    public  static  synchronized  SingletonExample3 getInstance(){
        if(instance == null){
            instance = new SingletonExample3();
        }
        return  instance;
    }
}

懒汉模式(双重检测,但是仍然线程不安全原因是多线程下指令重排!!)


/**
 * 懒汉模式 -》 双重同步锁单例模式
 * 单例实例在第一次使用时被创建
 */
public class SingletonExample4 {
    //私有构造对象
    private SingletonExample4(){

    }

    //1。memory = allocate() 分配对象内存空间
    //2。ctoInstance() 初始化对象
    //3。instance = memory 设置instance指向刚分配的内存

    //JVM和cpu优化 多线程下发生了指令重排
    //1。memory = allocate() 分配对象内存空间
    //3。instance = memory 设置instance指向刚分配的内存
    //2。ctoInstance() 初始化对象

   // 双重检测机制出现问题


    //单例对象
    private  static SingletonExample4 instance = null;
    //静态工厂方法  有性能开销
    public  static   SingletonExample4 getInstance(){
        if(instance == null){//双重检测机制  //B
            synchronized(SingletonExample.class) {//同步锁
                if (instance == null){
                    instance = new SingletonExample4(); // A线程执行到这时,完成了 指令的 1 ,3 还没进行初始化。这是B那个位置发现已经不为null了直接就返回回去了。但是 真实的时instance还没初始化完。
                }
            }
        }
        return  instance;
    }
}

懒汉模式(双重检测,加volatile 禁止指令重排, 推荐 )

/**
 * 懒汉模式 -》 双重同步锁单例模式
 * 单例实例在第一次使用时被创建
 */
public class SingletonExample5 {
    //私有构造对象
    private SingletonExample5(){

    }

    //1。memory = allocate() 分配对象内存空间
    //2。ctoInstance() 初始化对象
    //3。instance = memory 设置instance指向刚分配的内存

    //限制发生指令重排
    //单例对象 volatile 加上双重检测机制来禁止 指令重排
    private  volatile  static SingletonExample5 instance = null;
    //静态工厂方法  有性能开销
    public  static SingletonExample5 getInstance(){
        if(instance == null){//双重检测机制  //B
            synchronized(SingletonExample.class) {//同步锁
                if (instance == null){
                    instance = new SingletonExample5(); // A
                }
            }
        }
        return  instance;
    }
}

饿汉模式(推荐)

/**
 * 饿汉模式
 * 单例实例类装载时进行创建 不足当单例模式过多时,可能会影响性能问题,如果最终没调用,会造成资源浪费。  线程安全的
 */
public class SingletonExample2 {
    //私有构造对象
    private  SingletonExample2(){

    }
    //单例对象
    private  static  SingletonExample2 instance = new SingletonExample2();
    //静态工厂方法
    public  static  SingletonExample2 getInstance(){
        return  instance;
    }
}

饿汉模式(推荐)

/**
 * 饿汉模式
 * 单例实例类装载时进行创建
 */
public class SingletonExample6 {
    //私有构造对象
    private SingletonExample6(){

    }
    //单例对象
    private  static SingletonExample6 instance = null;

    static {
        instance = new SingletonExample6();
    }

    //静态工厂方法
    public  static SingletonExample6 getInstance(){
        return  instance;
    }
    public static void main(String[] args) {
        System.out.println(getInstance());
        System.out.println(getInstance());
    }

}

枚举(最安全 最推荐)

/**
 * 枚举模式 最安全
 */
public class SingletonExample7 {
    private  SingletonExample7(){
    }
    public static  SingletonExample7 getInstance(){
        return Singleton.INSTANCE.getInstance();
    }
    
    //私有枚举类  
    private  enum Singleton{
        INSTANCE;
        private  SingletonExample7 singleton;
        //JVM 保证这个方法绝对只调用一次
        Singleton(){
            singleton = new SingletonExample7();
        }
        public SingletonExample7 getInstance(){
            return  singleton;
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章