Java多线程双重加锁可能问题 Possible double check of field

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变量被赋值的时候对象已经是初始化过的,从而避免了上面说到的问题。

Java多线程双重加锁可能问题 Possible double check of field_第1张图片
image.png

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

你可能感兴趣的:(Java多线程双重加锁可能问题 Possible double check of field)