美文网首页
Java多线程双重加锁可能问题 Possible double

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

作者: 妖怪青同学 | 来源:发表于2018-04-08 17:39 被阅读0次

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

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

      本文链接:https://www.haomeiwen.com/subject/lhdmhftx.html