多个线程更新同一变量时的Java多线程

时间:2021-01-29 15:01:41

标签: java multithreading

这是程序

public class Thread2 implements Runnable {

    private static int runTill = 10000;
    private static int count = 0;
    @Override
    public void run() {
        for(int i=0;i<runTill;i++) {
            count++;
        }
    }
    
    public static void main(String s[]) {
        int iteration = 10;
        for(int i = 0; i < iteration ;i++) {
            Thread t = new Thread(new Thread2());
            t.start();
        }
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        System.out.println("Expected : "+(iteration * runTill));
        System.out.println("Actual : "+count);
    }

}

最后我希望计数等于(预期:100000)。我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:2)

count++ 的调用不是原子的:它首先必须加载 count,将其递增,然后将新值存储在变量中。如果没有同步,线程将在执行此操作期间交错。

获得所需内容的一种简单方法是使用 AtomicInteger

private static AtomicInteger count = new AtomicInteger();

@Override
public void run() {
    for(int i=0;i<runTill;i++) {
        count.incrementAndGet();
    }
}

答案 1 :(得分:0)

使用“比较并设置”而不是“递增并获取”

private static AtomicInteger count = new AtomicInteger();

@Override
public void run() {
    for(int i=0;i<runTill;i++) {

        //note: another thread might reach this point at the same time when i is 9,999
        // (especially if you have other codes running prior to the increment within the for loop)
        // then count will be added 2x if you use incrementAndGet
        boolean isSuccessful = count.compareAndSet(i, i+1);

        if(!isSuccessful) 
            System.out.println("number is not increased (another thread already updated i)");
    }
}

答案 2 :(得分:0)

正如评论所暗示的,除了需要同步访问(到 count,这里变成了 AtomicInteger),线程应该等待使用 Thread.join() 完成,而不是“猜测”他们的运行时间:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class Thread2 implements Runnable {

    private static int runTill = 10000;
    private static AtomicInteger count = new AtomicInteger();

    @Override
    public void run() {
        for (int i = 0; i < runTill; i++) {
            count.incrementAndGet();
        }
    }

    public static void main(String s[]) {
        int iteration = 10;
        List<Thread> threads = new ArrayList<Thread>();
        for (int i = 0; i < iteration; i++) {
            Thread t = new Thread(new Thread2());
            threads.add(t);
            t.start();
        }

        try {
            for (Thread t : threads)
                t.join();
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }

        System.out.println("Expected : " + (iteration * runTill));
        System.out.println("Actual : " + count);
    }
}
相关问题