双检锁
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");
}
}