3

以下代码应该通过使用 common 上的同步方法来防止 Data Racing。但由于某种原因,输出始终是 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);
    }
}
4

1 回答 1

5

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

synchronized((Integer)common){

重点是在每个线程中同步同一个对象。即使您commonInteger其设置为 ,只要将其分配给另一个值,它将是另一个对象。

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

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

 synchronized (lock) {
     common++;
 }

在这种特定情况下可能会更好,您可以考虑使用AtomicInteger. 这使您可以在没有任何同步的情况下执行以下操作。

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

 // no need to synchronize since that is handled by the class
 common.incrementAndGet();
于 2012-04-25T03:40:10.563 回答