Java单例模式的各种实现(饿汉、懒汉、静态内部类、static代码块、enum枚举类型)
饿汉模式
饿汉模式就是立即加载,在方法调用前,实例就已经被创建了,所以是线程安全的。
public class MyObject1 {
private static MyObject1 myObject1 = new MyObject1();
private MyObject1() {}
public static MyObject1 getInstance() {
return myObject1;
}
}
懒汉模式
懒汉就是延迟化加载,当需要使用的时候才进行实例化。
线程不安全
public class MyObject2 {
private static MyObject2 myObject2;
private MyObject2() {}
public static MyObject2 getInstance() {
if (myObject2 == null) {
myObject2 = new MyObject2();
}
return myObject2;
}
}
线程安全
线程安全但是效率低下
public class MyObject3 {
private static MyObject3 myObject3;
private MyObject3() {}
synchronized public static MyObject3 getInstance() {
if (myObject3 == null) {
myObject3 = new MyObject3();
}
return myObject3;
}
}
使用DCL双检查锁,线程安全而且效率得到提高,只将进行实例化的代码进行加锁。
public class MyObject4 {
private volatile static MyObject4 myObject4;
private MyObject4() {}
public static MyObject4 getInstance() {
if (myObject4 == null) {
synchronized (MyObject4.class) {
if (myObject4 == null) {
myObject4 = new MyObject4();
}
}
}
return myObject4;
}
}
使用静态内部类
线程安全,也是一种懒加载模式。
静态内部类中的静态成员只在第一次使用的时候加载,因此保证了线程安全。
public class MyObject5 {
private static class MyObject5Handle {
private static MyObject5 myObject5 = new MyObject5();
}
private MyObject5() {}
public static MyObject5 getInstance() {
return MyObject5Handle.myObject5;
}
}
使用static代码块
由于static代码块中内容在类加载的时候就执行了,因此保证了线程安全。
public class MyObject6 {
private static MyObject6 instance = null;
private MyObject6() {}
static {
instance = new MyObject6();
}
public static MyObject6 getInstance() {
return instance;
}
}
使用enum枚举
JVM会保证enum不能被反射并且构造器方法只执行一次,因此该单例是线程安全的。
public class MyObject7 {
private enum MyEnumSingleton {
enumFactory;
private MyObject7 myObject7;
private MyEnumSingleton() {
myObject7 = new MyObject7();
}
public MyObject7 getInstance() {
return myObject7;
}
}
public static MyObject7 getInstance() {
return MyEnumSingleton.enumFactory.getInstance();
}
}