单线程的情况下不加volatile和synchronized也是正确的单例。多线程情况下,如果你把volatile换成synchronized也是可以的,但是这样就是一个重量级,并发度会变得很差。换成volatile可以保证每个线程都可以得到instance变量的最新的值(底层的实现是,将每个线程栈桢中变量的拷贝实现,从共享区内存读取最新的值)。<br />如果不加下面的synchronized的话为什么不是线程安全的?这是因为每个对象创建会分成三步,而操作系统底层会对这个三步进行重排序,加上synchronized就会告诉操作系统不要对这三步重排序,这样保证了原子性和顺序性。(我这里面讲的比较简单,至于重排序你可以自己去查一查
public class Singleton1 {
private static volatile Singleton1 instance = null;
private Singleton1(){}
public static Singleton1 getInstance(){
if(instance == null){
synchronized (Singleton1.class){
if (instance == null){
instance = new Singleton1();
}
}
}
return instance;
}
}
class Singleton2{
private static Singleton2 instance = new Singleton2();
private Singleton2(){}
public static Singleton2 getInstance(){
return instance;
}
}
enum Singleton3{
instance;
public static void main(String[] args){
Singleton3 s3 = Singleton3.instance;
Singleton3 s4 = Singleton3.instance;
System.out.println(s3 == s4);
}
}
class Singleton4{
private static class Lazy{
private static Singleton4 instance = new Singleton4();
}
private Singleton4(){};
public static Singleton4 getInstance(){
return Lazy.instance;
}
}