前言
本文是Java面试复习系列中的单例模式,后面会陆续有该系列其他篇章,并且会一直维护。本系列都为网上资源整理而来,如有问题,及时联系。
单例模式
- 最重要的思想是构造器私有
饿汉式
//饿汉式单例
public class Hungry {
//饿汉式,一上来加载全部数据,可能会浪费空间
private byte[] data1 = new byte[1024 * 1024];
private byte[] data2 = new byte[1024 * 1024];
private byte[] data3 = new byte[1024 * 1024];
private byte[] data4 = new byte[1024 * 1024];
private Hungry() {
}
private final static Hungry HUNGRY = new Hungry();
public static Hungry getInstance() {
return HUNGRY;
}
}
懒汉式
public class LazyMan {
private LazyMan(){}
private volatile static LazyMan lazyMan;
private static LazyMan getInstance() {
if (lazyMan == null) {
synchronized (LazyMan.class){
if (lazyMan == null) {
lazyMan = new LazyMan ();
}
}
}
return lazyMan;
}
}
import java.lang.reflect.Constructor;
//懒汉式
public class LazyMan {
private static boolean qinjiang = false;
private LazyMan() {
synchronized (LazyMan.class) {
if (qinjiang == false) {
qinjiang = true;
} else {
throw new RuntimeException("不要试图用反射破坏异常");
}
// if (lazyMan != null) {
// throw new RuntimeException("不要试图用反射破坏异常");
// }
}
System.out.println(Thread.currentThread().getName() + "ok");
}
private volatile static LazyMan lazyMan;//为了避免指令重排造成问题,加volatile
//双重检测锁模式,懒汉式单例,DCL懒汉式
public static LazyMan getInstance() {
if (lazyMan == null) {
synchronized (LazyMan.class) {
if (lazyMan == null) {
lazyMan = new LazyMan(); //不是一个原子性操作
/**
* 1.分配内存空间
* 2.执行构造方法,初始化对象
* 3.把对象指向这个空间
*/
}
}
}
// if (lazyMan == null) {
// lazyMan = new LazyMan();
// }
return lazyMan;
}
//单线程下真缺
//多线程并发
// public static void main(String[] args) {
// for (int i = 0; i < 10; i++) {
// new Thread(() -> LazyMan.getInstance()).start();
// }
// }
//反射
public static void main(String[] args) throws Exception {
// LazyMan instance = LazyMan.getInstance();
Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
LazyMan instance2 = declaredConstructor.newInstance();
LazyMan instance3 = declaredConstructor.newInstance();
// System.out.println(instance);
System.out.println(instance2);
System.out.println(instance3);
}
}
静态内部类
//静态内部类实现
public class Holder {
private Holder(){}
public static Holder getInstance() {
return InnerClass.HOLDER;
}
public static class InnerClass{
private static final Holder HOLDER = new Holder();
}
}
枚举
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
//enum 是什么? 本身也是一个class类
public enum EnumSingle {
INSTANCE;
public EnumSingle getInstance(){
return INSTANCE;
}
}
class Test{
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
EnumSingle instance1 = EnumSingle.INSTANCE;
Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(String.class,int.class);
declaredConstructor.setAccessible(true);
EnumSingle instance2 = declaredConstructor.newInstance();
System.out.println(instance1);
System.out.println(instance2);
}
}