public class Singleton{
private static Singleton mSingleton;
private Singleton(){
}
public static Singleton getInstance(){
if(mSingleton == null){
mSingleton = new Singleton();\\A
}
return mSingleton;
}
}
上面的做法在多线程的时候会出现问题,比如有两个线程同时调用getInstance(),这时会new两个对象出来。
public class Singleton{
private static Singleton mSingleton;
private Singleton(){
}
public static Singleton getInstance(){
synchronized(Singleton.class){
if(mSingleton == null){
mSingleton = new Singleton();\\A
}
return mSingleton;
}
}
}
这种方式还是会有问题,就是高并发情况下多线程去抢夺锁,假如有几百个线程,其中有一个运气比较差,这个线程就会出现一直去getInstance,资源一直返回不回去,UI也不会得到更新。
public class Singleton{
private volatile static Singleton mSingleton;
private Singleton(){
}
public static Singleton getInstance(){
if(mSingleton == null){\\A
synchronized(Singleton.class){\\C
if(mSingleton == null)
mSingleton = new Singleton();\\B
}
}
return mSingleton;
}
}
注:volatile是防止cpu进行指令重排序,防止代码顺序被更改。
这种方式比较好的地方在于第一次创建实例时候就会同步所有的线程,以后再获取实例就会直接返回。
其实这个意义在于防止多个线程同时进入第一个if内,比如说线程A执行到A行,线程B执行到B行,线程B还没有返回。当线程A执行到C行,这时线程B初始化实例完毕,如果没有里面的再一次判断就会生成两个实例!所以两次的判断null还是有意义的。
原文地址:http://blog.csdn.net/rain_butterfly/article/details/45920857