我应该同步静态易失性变量吗?

2023-12-21

关于这个主题有几个问题,但大多数都回避了这个问题,因为这不是问题的意图。

如果我的类中有一个静态易失性:

private static volatile MyObj obj = null;

在下面的方法中我这样做:

public MyObj getMyObj() {
    if (obj == null) {
        obj = new MyObj();// costly initialisation
    }
    return obj;
}

我是否需要同步以确保只有一个线程写入该字段,或者任何写入对评估该字段的其他线程立即可见obj == null有条件的?

换句话说:易失性是否能让您不必同步对静态变量写入的访问?


你肯定需要some一种锁定以确保只有一个线程写入该字段。无论波动性如何,两个线程都可以“看到”obj为 null,然后两者都开始使用当前代码进行初始化。

就我个人而言,我会选择以下三个选项之一:

  • 在类加载时初始化(知道这会很懒,但不像等待那样懒)getMyObj首先被调用):

    private static final MyObj obj = new MyObj();
    
  • 使用无条件锁定:

    private static MyObj obj;
    private static final Object objLock = new Object();
    
    public static MyObj getMyObj() {
        synchronized(objLock) {
            if (obj == null) {
                obj = new MyObj();
            }
            return obj;
        }
    }
    
  • 使用嵌套类来实现惰性:

    public static MyObj getMyObj() {
        return MyObjHolder.obj;
    }
    
    private static class MyObjHolder {
        static final MyObj obj = new MyObj();
    }
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该同步静态易失性变量吗? 的相关文章

随机推荐