Java同步计数器 - get()怎么样?

Jak*_*zyk 3 java multithreading counter synchronization

众所周知,simple x++不是原子操作,实际上是read-increment-write操作.这就是它应该同步的原因.但那怎么样get()?我已经读过它应该同步,但有人可以解释我为什么?通过引入happens-before关系来避免内存一致性错误?当get()多个线程经常调用并且很少更改值时,情况如何呢?是不是synchronized get()放慢了速度?在该场景中是否有其他方法可以实现同步(不使用AtomicInteger)?就volatile在这里工作的关键字?

public class Counter {
    private int value;

    public synchronized int get() { return value; }
    public synchronized int increment() { return ++value; }
    public synchronized int decrement() { return --value; }
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

编辑:

我想说清楚.通过使用volatile我的意思是引入该关键字和去除synchronizedget()方法.我想知道它是否会使它成为线程安全的,但如果许多线程正在读取值并且很少更改它,那么它也会更有效.

Gra*_*ray 10

在该场景中是否有其他方法可以实现同步(不使用AtomicInteger)?

首先,AtomicInteger如果可以,你应该使用.我不确定你为什么不使用它.

volatile关键字会在这里工作吗?

是的,除了没有++.AtomicInteger提供安全增量而不锁定.如果你想自己滚动(出于一些疯狂的原因),那么你将需要阻止,或者你需要复制AtomicInteger内部旋转机制.

但是get()怎么样?我已经读过它应该同步,但有人可以解释我为什么?

AtomicInteger包装a volatile int以提供其功能.当您访问该volatile字段时,您get()也会穿过内存屏障.您需要跨越该内存屏障以确保如果另一个线程已更新该值,则调用该线程的线程将get()看到更新.否则,线程可能正在使用过时的值.