本文介绍了学习使用防止数据争用情况的线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码应该通过在common上使用synced方法来防止Data Racing.但是由于某种原因,输出始终为19915-19980.如果不是数据竞速,那不应该是20000吗?

The following code is supposed to prevent Data Racing by using the synchronized method on common. But for some reason the output is always 19915-19980. Shouldn't it be 20000 if it was not data racing?

public class SyncVarDataRace extends Thread {

    private static int common = 0;

    public void run(){
        synchronized((Integer)common){
            int local = common;
            local+=1;
            common = local;
        }
    }


    public static void main(String[] args) throws InterruptedException {
        SyncVarDataRace[] allThreads = new SyncVarDataRace[20000];

        for(int i = 0; i < allThreads.length; i++){
            allThreads[i] = new SyncVarDataRace();
        }

        for(SyncVarDataRace d: allThreads){
            d.start();
        }

        for(SyncVarDataRace d: allThreads){
            d.join();
        }

        System.out.println(common);
    }
}

推荐答案

您正在尝试在自动装箱的对象上进行同步,该对象每次都是不同的对象.

You are trying to synchronize on an auto-boxed object that will be a different object every time.

synchronized((Integer)common){

重点是要在每个线程中的同一对象上进行同步.即使将common设置为Integer,将其分配给另一个值后,它也会是另一个对象.

The whole point is to synchronize on the same object in each thread. Even if you made common be an Integer, as soon as you assign it to another value, it would be a different object.

您需要锁定一个常量对象.我建议定义一个可以同步的本地对象:

You need to lock on a constant object instead. I would recommend defining a local Object that you can synchronize on:

 private final static Object lock = new Object();
 private static int common = 0;
 ...

 synchronized (lock) {
     common++;
 }

在这种特定情况下可能会更好,您可以考虑使用AtomicInteger.这样一来,您无需进行任何同步即可执行以下操作.

It might be better in this specific case, you might consider using an AtomicInteger. That allows you do something like the following without any synchronization.

 private static AtomicInteger common = new AtomicInteger(0);
 ...

 // no need to synchronize since that is handled by the class
 common.incrementAndGet();

这篇关于学习使用防止数据争用情况的线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 22:40