This question already has answers here:
synchronized block for an Integer object
                                
                                    (3个答案)
                                
                        
                2年前关闭。
            
        

为什么变量“ count”最终不等于20000?

public class Main {
private Integer count = 0;

public void increment() {
    synchronized (count) {
        count++;
    }
}

public static void main(String[] args) {
    Main app = new Main();
    app.doWork();
}

public void doWork() {

    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int i=0; i<10000; i++) {
                increment();
            }
        }
    });

    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int i=0; i<10000; i++) {
                increment();
            }
        }
    });

    t1.start();
    t2.start();
    System.out.println(count);
}


线程似乎丢失了变量,但是什么时候发生?在使用AtomicInteger的情况下也会发生相同的情况。

附言您能否推荐一门不错的课程,并附有练习来学习Java多线程?)

最佳答案

您在count上同步。但是您的代码会更改count。在不同对象上同步的不同线程不能保证原子性。

使用单独的final监视对象进行同步。

另请参阅@BackSlash的答案,以确保您打印正确的最终结果。

编辑

他的答案归结为:如果您在不等待主线程线程完成处理的情况下打印结果,则会看到一些中间结果,甚至可能是0。

因此,您需要在打印最终结果之前在两个线程上调用join(),该线程将阻塞直到线程结束。

09-04 21:31
查看更多