关于这个主题有几个问题,但大多数都绕过这个问题,因为这不是问题的意图。
如果我的类中有静态 volatile:
private static volatile MyObj obj = null;
在下面的方法中我这样做:
public MyObj getMyObj() {
if (obj == null) {
obj = new MyObj();// costly initialisation
}
return obj;
}
我是否需要同步以确保只有一个线程写入该字段,或者任何写入是否立即对评估 obj == null
条件的其他线程可见?
换句话说:volatile 是否让您不必同步对静态变量的写入访问?
最佳答案
您肯定需要某种 类型的锁定来确保只有一个线程写入该字段。无论波动如何,两个线程都可以“看到”obj
为空,然后都开始使用您当前的代码进行初始化。
就我个人而言,我会选择以下三个选项之一:
在类加载时初始化(知道这会很懒,但不像等到首次调用
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(); }
关于java - 我应该同步静态易失变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10697451/