单例模式是在面试中是最容易被考到的设计模式,这是因为单例模式是设计模式中最简单的,几行代码就能搞定(现场手写代码);同时单例模式又有多种实现方式,涉及到线程安全、懒加载、序列化等问题。
单例模式一共分为5种:
// 饿汉模式,开始就创建实例,线程安全
public class Wife1 {
private static final Wife1 wife = new Wife1();
private Wife1() {}
public static Wife1 getWife() {
return wife;
}
}
不需要同步
,所有的线程都会看到同样的实例。final
使得 INSTANCE 不能修改,保证有且只有一个实例。// 懒汉模式,需要时才创建实例,需加锁
public class Wife2 {
private static Wife2 wife;
private Wife2() {}
public static synchronized Wife2 getWife() {
if (wife == null) {
wife = new Wife2();
}
return wife;
}
}
线程同步
的,效率低// 双重加锁,通过volatile关键字防止编译器重排序,Java 1.5以下不可用
public class Wife3 {
private volatile static Wife3 wife;
private Wife3() {}
public static synchronized Wife3 getWife() {
if (wife == null) {
synchronized (Wife3.class) {
if (wife == null) {
wife = new Wife3();
}
}
}
return wife;
}
}
volatile
关键字,在Java 1.5以下不可用// 静态内部类
public class Wife4 {
// 只有在需要时,才被JVM加载。加载类Wife4时,不加载内部类WifeHolder
private static class WifeHolder {
private static final Wife4 wife = new Wife4();
}
private Wife4() {}
public static Wife4 getWife() {
return WifeHolder.wife;
}
}
延迟加载
所有的Java版本
线程安全
// 枚举,《Effective Java》推荐方法,最简单、线程安全
public enum Wife5 {
INSTANCE;
}
线程安全