getValue() 中需要同步吗?需要挥发性吗?

is synchronized needed in getValue() ? & volatile needed?

我有一个 class 多线程应用程序:

public class A {
        private volatile int value = 0; // is volatile needed here?
    
        synchronized public void increment() { 
          value++; // Atomic is better, agree
        }
    
        public int getValue() { // synchronized needed ?
          return value;
        }
    }

关键字 volatile 为您提供可见性方面,否则您可能会读取一些陈旧的值。易失性读取添加了一个内存屏障,这样编译器、硬件或 JVM 就无法以违反内存模型提供的可见性保证的方式重新排序内存操作。根据内存模型,对易失性字段的写入 发生在 每次后续读取同一字段之前,因此您可以保证读取最新值。

还需要关键字 synchronized,因为您正在执行必须自动完成的复合操作 value++。您读取该值,在 CPU 中递增它,然后将其写回。所有这些动作都必须以原子方式完成。但是,您不需要 synchronize 读取路径,因为关键字 volatile 保证了可见性。事实上,在读取路径上同时使用 volatilesynchronize 会造成混淆,并且不会提供任何性能或安全优势。

通常鼓励使用原子变量,因为它们使用内置于 CPU 中的 CAS 指令使用非阻塞同步,从而产生低锁争用和更高的吞吐量。如果用原子变量写的话,就是这样了。

public class A {
    private final LongAdder value = new LongAdder();

    public void increment() {
        value.add(1);
    }

    public int getValue() {
        return value.intValue();
    }
}