在多线程计数器中实现同步。

huangapple go评论141阅读模式
英文:

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(&quot;Program started&quot;);

        AtomicInteger sum = new AtomicInteger(0);
        System.out.println(&quot;Initial Sum : &quot; + sum.get());

        for (int i = 0; i &lt; 100; i++) {
            Thread workerThread = new WorkerThread(sum, i);
            workerThread.start();
        }

        System.out.println(&quot;Final Sum : &quot; + 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 &lt; 100; i++) {
    Thread workerThread = new WorkerThread(sum, i);
    workerThread.start();
    myThreads.add(workerThread);
}
for(Thread t : myThreads) {
    t.join();
}

huangapple
  • 本文由 发表于 2020年7月23日 23:35:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/63057943.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定