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包装器对象sumsum值保持为0。有人能帮我弄清楚如何将Integer包装器传递到线程中并增加原始值吗?

问题是localSum += 1没有做你认为它会做的事情。

Integer对象是不可变的:不能更改Integer的值。localSum+=1语句创建一个新的Integer实例,并更改localSum变量以引用新实例。同时,main()例程的sum变量将始终引用原始的、不可变的实例。

@Murat Karagöz说;使用AtomicInteger"这将解决两个问题;

  1. AtomicInteger实例是可变的,并且
  2. 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实例本身。

最新更新