1.单例-懒汉式
1.线程不安全
略
2.同步方法单例
略
3.双重检测
public class LazyDoubleCheckSingleton {
private static volatile LazyDoubleCheckSingleton instance = null;
private LazyDoubleCheckSingleton(){}
public static LazyDoubleCheckSingleton newInstance(){
if(null == instance){
synchronized (LazyDoubleCheckSingleton.class){
if(null == instance){
instance = new LazyDoubleCheckSingleton();
}
}
}
return instance;
}
}18
1
public class LazyDoubleCheckSingleton {2
private static volatile LazyDoubleCheckSingleton instance = null;3
4
private LazyDoubleCheckSingleton(){}5
6
7
8
public static LazyDoubleCheckSingleton newInstance(){9
if(null == instance){10
synchronized (LazyDoubleCheckSingleton.class){11
if(null == instance){12
instance = new LazyDoubleCheckSingleton();13
}14
}15
}16
return instance;17
}18
}4.静态内部类
/**
* 静态内部类,
* 第一次加载LazySingleton2类时并不会初始化instance,只
* 有第一次调用getInstance方法时虚拟机加载SingletonHolder 并初始化instance ,
* 这样不仅能确保线程安全也能保证Singleton类的唯一性,
* 所以推荐使用静态内部类单例模式。
* @program: gof23
* @link: 55864455@qq.com
* @author: Mr.Xxm
* @create: 2020-02-08 22:18
**/
public class LazyInnerClassSingleton {
private LazyInnerClassSingleton(){
if(null != SingletonHolder.instance){
throw new RuntimeException("不允许创建多个LazyInnerClassSingleton实例");
}
}
public static LazyInnerClassSingleton newInstance(){
return SingletonHolder.instance;
}
private static class SingletonHolder{
private static final LazyInnerClassSingleton instance = new LazyInnerClassSingleton();
}
}x
1
/**2
* 静态内部类,3
* 第一次加载LazySingleton2类时并不会初始化instance,只4
* 有第一次调用getInstance方法时虚拟机加载SingletonHolder 并初始化instance ,5
* 这样不仅能确保线程安全也能保证Singleton类的唯一性,6
* 所以推荐使用静态内部类单例模式。7
* @program: gof238
* @link: 55864455@qq.com9
* @author: Mr.Xxm10
* @create: 2020-02-08 22:1811
**/12
public class LazyInnerClassSingleton {13
14
private LazyInnerClassSingleton(){15
if(null != SingletonHolder.instance){16
throw new RuntimeException("不允许创建多个LazyInnerClassSingleton实例");17
}18
}19
20
public static LazyInnerClassSingleton newInstance(){21
return SingletonHolder.instance;22
}23
24
private static class SingletonHolder{25
private static final LazyInnerClassSingleton instance = new LazyInnerClassSingleton();26
}27
}温馨提示:
1) 以上方式都能被反射获取,如果静止反射的话,需要再无参构造抛出异常,来禁止破坏单例

2) 被反序列化操作

反序列化之后,依然破坏了单例,这时候如果要保证单例 需要以下操作
/**
* 重写readResolve方法,只不过是覆盖了反序列化出来的对象
* 还是创建了两次,发生在JVM层面,相对来说比较安全
* 之前反序列化出来的对象会被GC回收
* @return
* @throws ObjectStreamException
*/
private Object readResolve() throws ObjectStreamException {
return INSTANCE;
}10
1
/**2
* 重写readResolve方法,只不过是覆盖了反序列化出来的对象3
* 还是创建了两次,发生在JVM层面,相对来说比较安全4
* 之前反序列化出来的对象会被GC回收5
* @return6
* @throws ObjectStreamException7
*/8
private Object readResolve() throws ObjectStreamException {9
return INSTANCE;10
}ObjectInputStream.readOrdinaryObject(boolean unshared) 方法2032行
5.枚举式单例
/**
* @program: gof23
* @link: 55864455@qq.com
* @author: Mr.Xxm
* @create: 2020-02-09 00:48
**/
public enum EnumSingleton {
INSTANCE;
private Object data;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public static EnumSingleton newInstance(){
return INSTANCE;
}
}24
1
/**2
* @program: gof233
* @link: 55864455@qq.com4
* @author: Mr.Xxm5
* @create: 2020-02-09 00:486
**/7
public enum EnumSingleton {8
9
INSTANCE;10
11
private Object data;12
13
public Object getData() {14
return data;15
}16
17
public void setData(Object data) {18
this.data = data;19
}20
21
public static EnumSingleton newInstance(){22
return INSTANCE;23
}24
}1) 反序列化分析


2) 反射分析

不能反射式地创建枚举对象,这是JDK为枚举天然保驾护航,保障其单例性
6.容器式单例
/**
* @program: gof23
* @link: 55864455@qq.com
* @author: Mr.Xxm
* @create: 2020-02-09 00:37
**/
public class ContainerSingleton {
private static Map<String, Object> ioc = new ConcurrentHashMap<>();
private ContainerSingleton() {
};
public static Object getBean(String className) {
if (!ioc.containsKey(className)) {
synchronized (ioc) {
if (!ioc.containsKey(className)) {
Object obj = null;
try {
obj = Class.forName(className).newInstance();
ioc.put(className, obj);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return ioc.get(className);
}
}29
1
/**2
* @program: gof233
* @link: 55864455@qq.com4
* @author: Mr.Xxm5
* @create: 2020-02-09 00:376
**/7
public class ContainerSingleton {8
private static Map<String, Object> ioc = new ConcurrentHashMap<>();9
10
private ContainerSingleton() {11
};12
13
public static Object getBean(String className) {14
if (!ioc.containsKey(className)) {15
synchronized (ioc) {16
if (!ioc.containsKey(className)) {17
Object obj = null;18
try {19
obj = Class.forName(className).newInstance();20
ioc.put(className, obj);21
} catch (Exception e) {22
e.printStackTrace();23
}24
}25
}26
}27
return ioc.get(className);28
}29
}

浙公网安备 33010602011771号