是否递增运算符,例如count++;在本地存储易失性数据线程?

我的目标是了解 volatile 关键字的工作原理。

我的预期结果: assertEquals 没有失败。

我的实际结果: assertEquals 失败。(有时实际计数值在 9991 到 9999 之间)。

我假设这是因为增量运算符 /count++等于

public void increment() {
  int temp = count;
  count = temp + 1;
}

考虑到这一点,该temp属性是线程本地存储的。我是真的吗?

计数器.java

public class Counter implements Runnable {
  private volatile int count = 0;
  public int getCount() { return count; }
  public void increment() { count++; }
  @Override
  public void run() { increment(); }
}

CounterTest.java

public class CounterTest {
  @Test
  void increment() {
    ExecutorService service = Executors.newFixedThreadPool(10);
    Counter counter = new Counter();
    for (int i = 0; i < 10000; i++) {
      service.execute(counter);
    }
    service.shutdown();
    service.awaitTermination(1, TimeUnit.SECONDS);
    assertEquals(10000, counter.getCount());
  }
}

回答

我的目标是了解 volatile 关键字的工作原理

如果这是您的目标,那么请开始查看提供JLS的保证volatilevolatile不是关于原子操作,即:count++;不是原子。因此,这:

assertEquals(10000, counter.getCount());

可能会在任何时间点失败。

volatile是关于某个线程在观察到另一个线程对该变量的写入值时应该“观察”的内容。有很多,字面意思是这意味着什么的例子,可能最著名的一个 是 this。从那里开始,将您的知识积累到JLS.


以上是是否递增运算符,例如count++;在本地存储易失性数据线程?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>