/** * 饿汉试 * Created by jw.chen on 2018/4/30. */ public class SingletonDemo1 { //注意修饰符为私有的private private static SingletonDemo1 singleton = new SingletonDemo1(); //注意构造方法一定要用private防止外部再次实例化对象,保证单例 private SingletonDemo1(){ } public static SingletonDemo1 getInstance(){ return singleton; } }
/** * 懒汉式 单例实现方式 * Created by jw.chen on 2018/4/30. */ public class SingletonDemo2 { /** * 这里需要注意 volatile保证instance实例可见性 * 修饰符为私有 static 保证全局唯一和访问权限控制 */ private static volatile SingletonDemo2 instance; /** * 这里用private修饰,防止外部再次实例化该bean, * 保证全局唯一的单例效果 */ private SingletonDemo2() { } /** * 这里使用双重锁校验来防止并发问题 * @return */ public static SingletonDemo2 getInstance() { if (instance == null) { synchronized (SingletonDemo2.class) { if (instance == null) { return instance = new SingletonDemo2(); //jvm优化(指令重排序) /**注意点 * 类的实例化需要的步骤 * 1 申请一块内存空间 * 2 在这块空间里实例化对象 * 3 instance引用指向地址空间 * 在指令重排序模式下可能出现先指向3 后执行2的情况,此时线程可能拿到一个未实例化好的对象, * 这也是为什么声明private static volatile SingletonDemo2 instance; * 需要使用volatile的原因,volatile避免指令重排序 */ } } } return instance; } }