Possible double check of field
This method may contain an instance of double-checked locking. This idiom is not correct according to the semantics of the Java memory model. For more information, see the web page http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html.
(指令重排优化导致)
private static ActivityLifeManager sInstance;
public static ActivityLifeManager getInstance() {
if (sInstance == null) {
synchronized (ActivityLifeManager.class) {
if (sInstance == null) {
sInstance = new ActivityLifeManager();
}
}
}
return sInstance;
}
双重加锁可能存在的一个问题就是
例如线程1已经分配了地址给instance 但是还没有初始化, 此时线程2 判断intance不是null 直接返回
解决办法1
volatile的一个语义是禁止指令重排序优化,也就保证了instance变量被赋值的时候对象已经是初始化过的,从而避免了上面说到的问题。
volatile关键字使线程不直接从cpu寄存器读取而是从栈
/*
* 为了避免JIT编译器对代码的指令重排序优化,可以使用volatile关键字,
* 通过这个关键字还可以使该变量不会在多个线程中存在副本,
* 变量可以看作是直接从主内存中读取,相当于实现了一个轻量级的锁。
*/
private volatile static ActivityLifeManager sInstance;
public static ActivityLifeManager getInstance() {
if (sInstance == null) {
synchronized (ActivityLifeManager.class) {
if (sInstance == null) {
sInstance = new ActivityLifeManager();
}
}
}
return sInstance;
}
解决办法2
public static ActivityLifeManager getInstance() {
return Singleton.Instance;
}
//同时保证延迟加载和线程安全
private static class Singleton {
static ActivityLifeManager Instance = new ActivityLifeManager();
}
https://blog.csdn.net/goodlixueyong/article/details/51935526
http://www.importnew.com/16127.html