2012-04-25 2 views
3

Le code suivant est supposé empêcher Data Racing en utilisant la méthode synchronisée sur common. Mais pour une raison quelconque, la sortie est toujours 19915-19980. Ne devrait-il pas être 20000 si ce n'était pas la course de données?Apprendre à utiliser des threads qui empêchent les conditions de course de données

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); 
    } 
} 

Répondre

5

Vous essayez de synchroniser sur un objet automatiquement mis en boîte qui sera un objet différent à chaque fois.

synchronized((Integer)common){ 

Le point entier est de synchroniser sur le même objet dans chaque thread. Même si vous avez fait common être un Integer, dès que vous l'affectez à une autre valeur, ce serait un objet différent.

Vous devez verrouiller un objet constant à la place. Je recommande la définition d'un objet local que vous pouvez synchroniser sur:

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

synchronized (lock) { 
    common++; 
} 

Il pourrait être préférable dans ce cas précis, vous pouvez envisager d'utiliser un AtomicInteger. Cela vous permet de faire quelque chose comme ce qui suit sans aucune synchronisation.

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

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