class Singleton {
private Singleton(){}
//懒汉式
private volatile static Singleton singleton = null;
public static Singleton getInstance() {
//这里使用了Double checked locking
//只有第一次会进入同步代码块产生对象,后面就不会进入同步代码块,提升效率
//但是存在问题,Synchronized能保证原子性、可见性、有序性
//但是是在synchronized同步代码块外面的singleton变量不受monitor控制
//第一个线程还未完全将构造方法执行完毕,如果在构造方法中还要执行很多初始化操作,那么第二个线程获取的singleton将是一个未初始化完毕的单例
//对singleton使用volatile修饰即可,加入了写屏障,可以禁止指令重排序
if(singleton == null) {
synchronized (Singleton.class) {
if(singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
return singleton;
}
}
这里分析一个重要观点:
synchronized到底能不能保证 有序性?
前提条件:如果Synchronized中的变量完全受synchronized管理控制,那么就能够保证有序性,不会有发生指令重排序的问题。所以Synchronized是能够保证有序性的。
前提条件:如果Synchronized中的变量没有完全受Synchronized管理控制,那么就不能保证有序性,会发生指令重排序的问题。所以Synchronized是不能够保证有序性的,这个时候就需要给变量添加volatile关键字修饰,来保证变量的有序性,防止指令的重排序。