单例模式
饿汉式单例
package com.edgar.singleton;
// 饿汉式单例
public class Hungry {
// 类加载就会创建对象,可能会浪费空间,所以我们想出了懒汉式单例模式
private final static Hungry HUNGRY = new Hungry();
private Hungry() {
}
public static Hungry getInstance() {
return HUNGRY;
}
public static void main(String[] args) {
Hungry hungry1 = Hungry.getInstance();
Hungry hungry2 = Hungry.getInstance();
System.out.println(hungry1);
System.out.println(hungry2);
}
}
懒汉式单例
package com.edgar.singleton;
// 懒汉式单例
public class LazyMan {
private volatile static LazyMan lazyMan = null;
private LazyMan() {
}
// 双重检测锁模式 懒汉式单例 DCL(Double check lock)懒汉式
public static LazyMan getInstance() {
if (lazyMan == null) {
synchronized (LazyMan.class) {
if (lazyMan == null) {
lazyMan = new LazyMan();// 不是一个原子性操作
/*
* 1.分配内存空间
* 2.执行构造方法,初始化对象
* 3.把这个对象指向这个空间
*
* A线程由于指令重排,按132的顺序走,当走到3时,B线程开始,这时lazyMan!=null,会直接执行return lazyMan;
* 但此时LazyMan还没有完成构造方法,会有问题的,所以给lazyMan变量加上关键字volatile来防止重排序问题
* */
}
}
}
return lazyMan;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
System.out.println(LazyMan.getInstance());
}).start();
}
}
}
另外,单例模式都可以通过Class反射来破解。