import java.io.Serializable;public class two implements Serializable{ private two(){ //防止反射 破环单例 if(INSTANCE != null){ throw new RuntimeException("error"); } } private static final two INSTANCE = new two(); public static two getIn() { return INSTANCE; }//防止被反序列化 破坏单例 public Object readResolve(){ return INSTANCE; }}
可能会被Unsafe破坏单例
enum类型的饿汉式public enum enumOne { INSTANCE; public static enumOne getInstance() { return INSTANCE; }}
可能会被Unsafe破坏单例
懒汉式import java.io.Serializable;public class lanOne implements Serializable{ private lanOne(){}; private static lanOne INSTANCE = null; public static lanOne getINSTANCE() { if(INSTANCE == null){ INSTANCE = new lanOne(); } return INSTANCE; }}
DCL懒汉式(双检锁)public class lanOne implements Serializable{ private lanOne(){}; private static volatile lanOne INSTANCE = null; public static lanOne getINSTANCE() {if(INSTANCE == null){ synchronized(lanOne.class){ if(INSTANCE == null){ INSTANCE = new lanOne(); } }} return INSTANCE; }}
为什么要加volatile?
在编译的代码 无关紧要的代码执行顺序是有可能被改变的,比如构造对象,和给对象赋值=。这两步是有可能被优化为先赋值,再构造对象。如果再多线程情况下,第一个线程赋值,但是还没构造对象,这时候第二个线程,直接执行return.那第二个线程拿到的对象是不完整的。
添加volatile以后,添加内存屏障,要求赋值之后不能进行构造操作,那么就只能先构造了。
内部类 懒汉式public class innerClass { private innerClass(){}; public static class holder{ static innerClass INSTANCE = new innerClass(); } public static innerClass getINSTANCE() { return holder.INSTANCE; }}
单例设计模式在jdk中的体现Runtime 饿汉式System 双检锁 懒汉式