public class Main {
private static Main instance = null;
private Main() {}
public static Main getInstance() {
if(null == instance) instance = new Main();
return instance;
}
}
就是改进了check-then-act的原子性问题
public class Main {
private static Main instance = null;
private Main() {}
public static Main getInstance() {
synchronized(Main.class) {
if(null == instance) instance = new Main();
}
return instance;
}
}
public class Main {
private static Main instance = null;
private Main() {}
public static Main getInstance() {
if(null == instance) synchronized(Main.class) {
if(null == instance) instance = new Main(); // 问题出现在初始化
}
return instance;
}
}
注意可见性是正确的,错误在于初始化的重排序
上一篇文章已经写了3个步骤,一个线程在判断第一个if的时候可能另一个线程执行到第二个步骤就写入引用了,这时返回的是默认值
既然重排序有问题那当然要volatile
public class Main {
private static volatile Main instance = null;
private Main() {}
public static Main getInstance() {
if(null == instance) synchronized(Main.class) {
if(null == instance) instance = new Main();
}
return instance;
}
}
利用class文件对于内部类的特性,实现上够简单
public class Main {
private static class InstanceHolder {
final static Main INSTANCE = new Main();
}
public static Main getInstance() {
return InstanceHolder.INSTANCE;
}
}
仅访问Singleton本身不会使Singleton.INSTANCE初始化
public enum Singleton {
INSTANCE;
Singleton() {}
public void doSomething() {}
}
public class Main {
public static void main() {
new Thread() {
public void run() {
Singleton.INSTANCE.doSomething();
}
}.start();
}
}
补充一下奇怪的术语:懒汉式、饿汉式
其中懒汉式就是带Lazy加载的意思,比如1、2
而饿汉式我并不太清楚字面上的意思。。应该是指内存宽裕吧。。就是static直接返回的那种,显然不如静态内部类
public class Main {
private static Main instance = new Main();
private Main() {}
public static Main getInstance() { return instance; }
}
改进方法就是在构造方法创建保护null的判断
解决方法是重写readResolve()
方法,使得它在方法内直接返回instance
原文:https://www.cnblogs.com/caturra/p/10884130.html