单例模式

双检锁

package com.design.singleton;



/**
 * 双检式
 *
 * @author weitian.chen
 * @date 2021/8/27 10:02
 */
public class Singleton {

    /** 将构造方法私有化,不让外部程序可以随便新建对象 */
    private Singleton(){}

    /** 1.新建参数instance为null,采用的是懒汉机制,只有需要的时候才创建对象,
     * 2.与此相对的是饿汉机制,新建参数时直接创建Singleton对象
     * 3.如果不使用volatile修饰符,JVM指令重排时,仍然可能发生线程不安全的情况(同时创建两个对象),该修饰符阻止了变量访问前后的指令重排,保证执行顺序*/
    private volatile static Singleton instance = null;

    public static Singleton getSingleton(){

        /** 存在一个问题,如两个线程同时访问时,可能会出现同时判断为空,然后新建了两个对象 */
//        if(instance==null){
//            instance=new Singleton();
//        }
        
        /** 双重检测机制,此处不能使用对象锁,而应该使用类锁,
         * 并且需要进行第二次判断,否则当线程A创建完对象时,不判断,线程B仍然会创建对象 */
        if(instance==null){
            synchronized (Singleton.class){
                if (instance==null){
                    instance=new Singleton();
                }
            }
        }
        return instance;
    }
}


枚举

package com.design.singleton;

/**
 * 枚举单例
 *
 * @author weitian.chen
 * @date 2021/8/27 15:05
 */
public enum  Singleton {
    
    /** 线程安全的单例模式,能防止通过反射构建对象,随类加载而加载 */
    INSTANCE ;

    public void doSomething(){
        System.out.println("doSomething");
    }
}

posted @ 2021-11-16 15:58  2月2日  阅读(30)  评论(0)    收藏  举报