java易失性变量是否需要同步访问?
我在理解Java中的可变变量时有点困难
我有一个参数化类,其中包含一个易失变量,如下所示:
public class MyClass<T> {
private volatile T lastValue;
// ... other code ...
}
我必须对lastValue
执行某些基本操作,如果不为null,则包括get值
这些操作需要同步吗?我能用下面的方法逃脱吗
public void doSomething() {
String someString;
...
if (lastValue != null) {
someString += lastValue.toString();
}
}
或者我需要将空检查粘贴到同步块中吗
public void doSomething() {
String someString;
...
synchronized(this) {
if (lastValue != null) {
someString += lastValue.toString();
}
}
}
我知道对于get和set这样的原子操作,不应用同步(例如public T getValue() { return lastValue; }
)应该可以。但我不确定非原子操作
# 1 楼答案
这在很大程度上取决于类型T的属性。在最简单的情况下,T是一个不可变的类型,也就是说,无论您读取的T值是多少,它都不会在以后更改其内部状态。在这种情况下,不需要同步,只需将引用读入局部变量,并根据需要使用它
如果T是一个可变类型,那么您需要防止实例在使用它时更改其状态。在这种情况下,您需要特别确保T实例受其保护的同步。在上同步这个通常不能确保,它不会阻止你从任何其他地方改变t的状态。特定T的正确锁必须由规则定义(并且没有语言元素确保您不会违反这些规则)
在特殊情况下,T是可变的,您将这个定义为正确的锁,您需要同步,但不再需要volatile
也就是说,将volatile与synchronized结合使用看起来很可疑