英文:
Achieve synchronization in multi-threaded counter Java
问题
我有一个程序,我编写了多线程来递增计数器。我正在尝试使用同步来避免竞争条件。
这是代码,
主方法
import java.util.concurrent.atomic.AtomicInteger;
public class Counter {
public static void main(String... args) {
System.out.println("程序已启动");
AtomicInteger sum = new AtomicInteger(0);
System.out.println("初始总和:" + sum.get());
for (int i = 0; i < 100; i++) {
Thread workerThread = new WorkerThread(sum, i);
workerThread.start();
}
System.out.println("最终总和:" + sum.get());
}
}
WorkerThread
import java.util.concurrent.atomic.AtomicInteger;
public class WorkerThread extends Thread {
private final AtomicInteger localSum;
public WorkerThread(AtomicInteger sum, int i){
localSum = sum;
System.out.println(localSum.get());
}
@Override
public void run() {
synchronized (localSum) {
localSum.incrementAndGet();
}
}
}
但显然同步不起作用(最终没有输出 100)。非常感谢您的帮助。
英文:
I have a program which I wrote to run multiple threads that increment counter. I am trying to use synchronization to avoid race conditions.
This is the code,
Main method
import java.util.concurrent.atomic.AtomicInteger;
public class Counter {
public static void main(String... args) {
System.out.println("Program started");
AtomicInteger sum = new AtomicInteger(0);
System.out.println("Initial Sum : " + sum.get());
for (int i = 0; i < 100; i++) {
Thread workerThread = new WorkerThread(sum, i);
workerThread.start();
}
System.out.println("Final Sum : " + sum.get());
}
}
WorkerThread
import java.util.concurrent.atomic.AtomicInteger;
public class WorkerThread extends Thread {
private final AtomicInteger localSum;
public WorkerThread(AtomicInteger sum, int i){
localSum = sum;
System.out.println(localSum.get());
}
@Override
public void run() {
synchronized (localSum) {
localSum.incrementAndGet();
}
}
}
But apperently the synchronization does not work as expected (It does not prontout 100 at the end). Any help will be highly appreciated.
答案1
得分: 2
你的程序存在几个问题:
- 你正在使用AtomicInteger,因此不需要显式地进行同步。
- 你没有等待线程完成。只有在所有线程运行完毕后,总和才会达到100。
将你创建的线程放入一个列表中,在打印结果之前使用join()
方法等待它们执行完毕。
英文:
There are several problems with your program:
- You are using AtomicInteger, so you don't need to synchronize explicitly.
- You are not waiting for the threads to finish. The sum will reach 100 after all the threads run.
Put the threads you created in a list, and join()
them before you print the result.
答案2
得分: 1
你的synchronized
是完全不必要的。AtomicInteger
本身足以使代码线程安全。您需要一个可变的非原子整数(标准JDK没有提供)来实际查看synchronized
在这里的工作原理,所以这个示例不太适合用于说明那个。
你的错误在于假设当主线程调用sum.get()
时,所有线程都已经完成运行。你可以通过让主线程在所有已启动的线程上调用join()
来确保这一点,例如:
for (int i = 0; i < 100; i++) {
Thread workerThread = new WorkerThread(sum, i);
workerThread.start();
myThreads.add(workerThread);
}
for(Thread t : myThreads) {
t.join();
}
英文:
Your synchronized
is completely unnecessary. The AtomicInteger
by itself is enough to make the code thread-safe. You would need a mutable non-atomic integer (which the standard JDK doesn't have) to actually see how synchronized
works here, so this example isn't very good for that.
Your mistake is assuming that all the threads have finished running when the main thread calls sum.get()
. You can make sure of that by having the main thread call join()
on all the started threads for example:
for (int i = 0; i < 100; i++) {
Thread workerThread = new WorkerThread(sum, i);
workerThread.start();
myThreads.add(workerThread);
}
for(Thread t : myThreads) {
t.join();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论