Java 学习使用防止数据争用条件的线程

Java 学习使用防止数据争用条件的线程,java,multithreading,race-condition,Java,Multithreading,Race Condition,下面的代码应该是通过在common上使用synchronized方法来防止数据争用。但由于某些原因,输出总是19915-19980。如果不是数据竞赛,它不应该是20000吗 public class SyncVarDataRace extends Thread { private static int common = 0; public void run(){ synchronized((Integer)common){ int lo

下面的代码应该是通过在common上使用synchronized方法来防止数据争用。但由于某些原因,输出总是19915-19980。如果不是数据竞赛,它不应该是20000吗

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);
    }
}
公共类SyncVarDataRace扩展线程{
私有静态int公共=0;
公开募捐{
已同步((整数)公共){
int局部=公共;
局部+=1;
普通=本地;
}
}
公共静态void main(字符串[]args)引发InterruptedException{
SyncVarDataRace[]所有线程=新的SyncVarDataRace[20000];
对于(int i=0;i
您试图在自动装箱的对象上进行同步,该对象每次都是不同的对象

synchronized((Integer)common){
关键是在每个线程中的同一个对象上进行同步。即使将
公共
设置为
整数
,只要将其指定给另一个值,它也将是另一个对象

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

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

 synchronized (lock) {
     common++;
 }
<> p>在这个特定的情况下可能更好,您可以考虑使用<代码> AtomicInteger < /代码>。这允许您在不进行任何同步的情况下执行以下操作

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

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