有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    这在很大程度上取决于类型T的属性。在最简单的情况下,T是一个不可变的类型,也就是说,无论您读取的T值是多少,它都不会在以后更改其内部状态。在这种情况下,不需要同步,只需将引用读入局部变量,并根据需要使用它

    如果T是一个可变类型,那么您需要防止实例在使用它时更改其状态。在这种情况下,您需要特别确保T实例受其保护的同步。在上同步这个通常不能确保,它不会阻止你从任何其他地方改变t的状态。特定T的正确锁必须由规则定义(并且没有语言元素确保您不会违反这些规则)

    在特殊情况下,T是可变的,您将这个定义为正确的锁,您需要同步,但不再需要volatile

    也就是说,将volatile与synchronized结合使用看起来很可疑