我应该同时使用锁定和易失性吗?

时间:2014-06-22 21:08:28

标签: java locking volatile

我对volatile的理解是它确保始终从内存中读取值,所以据我所知,在下面的示例中,myObject变量需要是volatile才能避免{NullPointerException变量1}}被抚养:

private final Object lock = new Object();
private MyObject myObject = null;

//...

synchronized (lock) {
    if (myObject == null) {
        myObject = new MyObject();
    }

    myObject.blah();

    // some other stuff that I want synchronized
}

myObject仅在同步块中触及。 lock仅用于同步该块。

这是对的吗?

稍微改写一下,我的问题是......想象两个线程正在击中该代码。第一个线程锁定并设置myObject,调用.blah()以及synchronized块中的任何其他代码并退出synchronized块。这允许线程2进入同步块。如果不将myObject设置为易变,是否仍有可能将myObject == null评估为true

2 个答案:

答案 0 :(得分:3)

synchronized块将确保其他线程可以看到内存更新。没有必要使myObject易变。

来自Intrinsic Locks and Synchronization

  

当一个线程释放一个内部锁时,就会发生一次   在该行动与任何后续行动之间建立关系   获得同样的锁。

答案 1 :(得分:0)

我认为这里不需要volatile,因为进入synchronized块的每个线程都在检查myObject引用,所以当第一个线程进入块时,myObject应该是即时的,其他线程通过检查是myObject而不是null。对我来说看起来不错。

编辑:我希望只有这一个块你想要使用myObect参考,并且你不会在同步块之前或之后更改这个参考。