我在理解 Java 中的 volatile 变量时遇到一点困难。
我有一个参数化类,其中包含一个 volatile 变量,如下所示:
public class MyClass<T> {
private volatile T lastValue;
// ... other code ...
}
我必须针对 lastValue
实现某些基本操作,包括 get-value-if-not-null。
这些操作需要同步吗?我可以通过以下方法逃脱吗?
public void doSomething() {
String someString;
...
if (lastValue != null) {
someString += lastValue.toString();
}
}
或者我是否需要将空检查粘贴到同步块(synchronized block)中?
public void doSomething() {
String someString;
...
synchronized(this) {
if (lastValue != null) {
someString += lastValue.toString();
}
}
}
我知道对于像 get 和 set 这样的原子操作,我应该可以不应用同步(例如 public T getValue() { return lastValue; }
)。但我不确定非原子操作。
最佳答案
volatile
保证可见性(一个线程所做的更改将被其他线程看到)但它不保证多个操作的原子性。
是的,lastValue
可以在 if (lastValue != null)
和 someString += lastValue.toString( );
并且您的代码可能会抛出 NullPointerException
。
您可以添加同步(但您需要同步对变量的所有写访问),或者对于那个简单的用例,您可以使用局部变量:
public void doSomething() {
String someString;
T lastValueCopy = lastValue;
if (lastValueCopy != null) {
someString += lastValueCopy.toString();
}
}
关于java - volatile 变量是否需要同步访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16965724/