java - Java 多线程计数器不工作
问题描述
我正在尝试 Java 多线程计数器。我首先尝试在没有任何同步的情况下观察竞态条件。但是我的计数器没有被工作线程增加。
代码 - 主要方法
public static void main(String... args) {
System.out.println("Program started");
Integer sum = 0;
System.out.println("Initial Sum : " + sum);
for (int i = 0; i < 100; i++) {
WorkerThread workerThread = new WorkerThread(sum, i);
workerThread.run();
}
System.out.println("Final Sum : " + sum);
}
代码 - WorkerThread 类
public class WorkerThread implements Runnable {
private Integer localSum;
public WorkerThread(Integer sum, int i){
localSum = sum;
System.out.println(localSum);
}
@Override
public void run() {
localSum += 1;
}
}
我想知道为什么递增localSum
不会影响 Integer wrapper object sum
。该sum
值保持在 0。谁能帮我弄清楚如何将 Integer 包装器传递到线程中并增加原始值?
解决方案
问题是它localSum += 1
没有做你认为它做的事情。
Integer
对象是不可变的:您不能更改Integer
. 该localSum+=1
语句创建一个新 Integer
实例,并将localSum
变量更改为引用新实例。同时,main()
例程的sum
变量总是引用原始的、不可变的实例。
@Murat Karagöz 说,“使用AtomicInteger
.” 这将解决两个问题;
AtomicInteger
实例是可变的,并且- 该
ai.incrementAndGet()
操作和其他AtomicInteger
操作是线程安全的。
您的程序,如所写,不需要线程安全,但是一旦您更改它以实际创建多个线程,就需要它。
AtomicInteger
如果您制作所有变量,它将帮助您正确处理final
。例如;
public class WorkerThread implements Runnable {
private final AtomicInteger localSum;
public WorkerThread(AtomicInteger sum, int i){
localSum = sum;
System.out.println(localSum.get());
}
...
}
您不想意外更改localSum
字段的值(即,您不想更改AtomicInteger
它指向的实例) 您想改变AtomicInteger
实例本身。
推荐阅读
- excel - 如何在Excel中相对于对象定位表格
- swift - 检查应用程序中端口在哪个服务器上打开
- sql - 在 PostgreSql 中查找包含字符串的第一个数组值
- android - 如何访问 USB 驱动器的根文件夹?
- arrays - “文章”类型的值没有下标
- pine-script - Tradingview的策略测试器
- android - Android:在 CalendarView 中设置选定日期的背景颜色(不是 DatePicker)?
- snowflake-cloud-data-platform - 设置存储集成时在我的谷歌云帐户中看不到 STORAGE_GCP_SERVICE_ACCOUNT
- django - 如何修复 504 网关超时错误?
- list - 函数上的泛型类型不正确对应