【发布时间】:2025-12-04 09:40:01
【问题描述】:
只是为了试验多线程概念,我正在实现我自己的 AtomicInteger 版本,它使用悲观锁定。它看起来像这样:
public class ThreadSafeInt {
public int i; // Should this be volatile?
public ThreadSafeInt(int i) {
this.i = i;
}
public synchronized int get() {
return i;
}
public synchronized int getAndIncrement() {
return this.i++;
}
// other synchronized methods for incrementAndGet(), etc...
}
我编写了一个测试,它接受一个 ThreadSafeInt 实例,将它提供给数百个线程,并使每个线程调用 getAndIncrement 100,000 次。我看到的是所有增量都正确发生,整数的值恰好是(number of threads) * (number of increments per thread),即使我没有在原始实例变量i 上使用volatile。我预计如果我没有使i volatile,那么我会遇到很多可见性问题,例如,线程1 将i 从0 增加到1,但线程2 仍然看到0 的值并且还会增加它仅1,导致最终值小于正确值。
我了解可见性问题是随机发生的,并且可能取决于我的环境属性,因此即使存在可见性问题的固有可能性,我的测试也可以正常工作。所以我倾向于认为 volatile 关键字仍然是必要的。
但这是正确的吗?或者我的代码是否有一些属性(也许它只是一个原始变量等),我实际上可以信任它来消除对 volatile 关键字的需要?
【问题讨论】:
标签: java multithreading volatile