说我有两个线程和一个对象.一个线程分配对象:
public void assign(MyObject o) {
myObject = o;
}
Run Code Online (Sandbox Code Playgroud)
另一个线程使用该对象:
public void use() {
myObject.use();
}
Run Code Online (Sandbox Code Playgroud)
变量myObject是否必须声明为volatile?我想知道什么时候使用volatile而什么时候不用,这让我很困惑.是否有可能第二个线程在其本地内存缓存中保留对旧对象的引用?如果没有,为什么不呢?
非常感谢.
Kev*_*vin 11
我试图了解何时使用volatile而不是
你应该大多避免使用它.改为使用AtomicReference(或适当的其他原子类).记忆效应是相同的,意图更清晰.
我强烈建议您阅读优秀的Java Concurrency in Practice以便更好地理解.
抛弃复杂的技术细节,您可以看到volatile更少或更多作为变量的synchronized修饰符.当您想要同步访问方法或块时,您通常希望使用修饰符,如下所示:synchronized
public synchronized void doSomething() {}
Run Code Online (Sandbox Code Playgroud)
如果您想"同步"对变量的访问,那么您希望使用volatile修饰符:
private volatile SomeObject variable;
Run Code Online (Sandbox Code Playgroud)
在幕后他们做了不同的事情,但效果是一样的:对于下一个访问线程,更改立即可见.
在您的具体情况下,我认为volatile修饰符没有任何价值.在volatile不以任何方式将线程分配对象将运行保证之前使用该对象的线程.反过来也可以这样好.您可能只想先在use()方法中执行nullcheck .
更新:另见本文:
对变量的访问就像包含在同步块中一样,自身同步.我们在第二点说"好像",因为至少对程序员来说(并且可能在大多数JVM实现中)没有涉及实际的锁对象.