1. 懒汉模式(double check), 线程安全, 效率不高, 可以延迟加载
public class Singleton1 implements Serializable {
// 用volatile修饰instance, 禁止指令重排序, 为保证多线程安全
private volatile static Singleton1 instance = null;
private Singleton1() {
// 防止反射调用私有构造方法(跳过安全检查), 重复实例化实例
if (instance != null) {
throw new RuntimeException("error:instance=" + instance);
}
}
public static Singleton1 getInstance() {
if (instance == null) {
synchronized (Singleton1.class) {
if (instance == null) {
instance = new Singleton1();
}
}
}
return instance;
}
private Object readResolve() {
return instance; // 防止反序列化重复实例化实例
}
}
2. 饿汉模式, 线程安全, 效率高, 但是不能延迟加载
public class Singleton2 implements Serializable {
private static Singleton2 instance = new Singleton2();
private Singleton2() {
// 防止反射调用私有构造方法(跳过安全检查),重复实例化实例
if (instance != null) {
throw new RuntimeException("error:instance isn't null " + instance);
}
}
public static Singleton2 getInstance() {
return instance;
}
private Object readResolve() {
return instance; // 防止反序列化重复实例化实例
}
}
3. 私有静态内部类, 线程安全, 调用效率高, 可以延迟加载
public class Singleton3 {
private Singleton3() {
}
private static class Singleton0 {
private static final Singleton3 instance = new Singleton3();
}
/*
* 获取私有静态内部类中的实例对象
*/
public static Singleton3 getInstance() {
return Singleton0.instance;
}
}
3种方式的性能分析:
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
int countNum = 1000;
final CountDownLatch count = new CountDownLatch(countNum);
for (int i = 0; i < countNum; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 1000000; i++) {
// Singleton1.getInstance(); // 懒汉模式(double check)
// Singleton2.getInstance(); //饿汉模式
Singleton3.getInstance(); // 私有静态内部类
}
count.countDown();
}
}).start();
}
count.await();
long end = System.currentTimeMillis();
System.out.println(end - start);
}
Console输出:
懒汉模式(double check): 310ms
饿汉模式: 150ms
私有静态内部类: 160ms
来源:oschina
链接:https://my.oschina.net/u/2503731/blog/659209