单例模式分为: 饿汉式单例 和 懒汉式单例 、登记式单例
我们这只讲前两种单例!
一、饿汉式单例
package single;
public class Hungry {
private Hungry() {}
private static final Hungry single = new Hungry();
//静态工厂方法
public static Hungry getInstance() {
return single;
}
}
二、懒汉式单例
package single;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Lazy {
private Lazy() {
// synchronized (Lazy.class){
if(single!=null){
throw new RuntimeException("不要试图反射破坏异常");
}
// }
System.out.println(Thread.currentThread().getName()+"OK");
}
private volatile static Lazy single=null; //volatile避免指令重排
//DCL double check lazy 双重检查锁
public static Lazy getInstance() {
if (single == null) {
synchronized (Lazy.class){
if (single == null) {
single = new Lazy(); //不是原子性操作
// System.out.println(single);
}
}
}
return single;
}
// 多线程并发
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//1.
// for (int i = 0; i < 10; i++) {
// new Thread(()->{
// Lazy.getInstance();
// }).start();
// }
//2.
// Lazy s = Lazy.getInstance();
// System.out.println(s);
// Lazy a = Lazy.getInstance();
// System.out.println(a);
//3.反射
Lazy instance = Lazy.getInstance();
Constructor declaredConstructor = Lazy.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
Lazy instance2 =declaredConstructor.newInstance();
System.out.println(instance);
System.out.println(instance2);
}
}
三、总结



