如何在Java中正确使用volfine关键字?

2022-09-04 01:12:49

假设我有两个线程和一个对象。一个线程分配对象:

public void assign(MyObject o) {
    myObject = o;
}

另一个线程使用以下对象:

public void use() {
    myObject.use();
}

变量 myObject 是否必须声明为易失性?我试图了解何时使用挥发性,何时不使用,这让我感到困惑。第二个线程是否有可能在其本地内存缓存中保留对旧对象的引用?如果没有,为什么不呢?

多谢。


答案 1

我试图了解何时使用易失性,何时不使用

您主要应该避免使用它。请改用原子引用(或在适当的情况下使用其他原子类)。记忆效果是相同的,意图更加清晰。

我强烈建议您阅读优秀的 Java 并发实践,以便更好地理解。


答案 2

抛开复杂的技术细节,您可以看到或多或少地作为变量的修饰符。当您想要同步对方法或块的访问时,您通常希望按如下方式使用修饰符:volatilesynchronizedsynchronized

public synchronized void doSomething() {}

如果要“同步”对变量的访问,则希望使用修饰符:volatile

private volatile SomeObject variable;

在幕后,他们做了不同的事情,但效果是一样的:对于下一个访问线程,更改会立即可见。

在您的特定情况下,我不认为修饰符有任何价值。不以任何方式保证分配对象的线程将在使用该对象的线程之前运行。反过来,它可以一样好。您可能只想先在方法中执行空检查。volatilevolatileuse()

更新:另请参阅此文章

对变量的访问就像它被包含在一个同步的块中,在它本身上同步。我们在第二点中说“好像”,因为至少对于程序员来说(可能在大多数JVM实现中),没有涉及实际的锁定对象


推荐