2017-09-04 1 views
0

On m'a dit dans une interview que la valeur minimale du compteur après avoir exécuté le code suivant est 2. Comment est-ce possible?valeur minimale d'un compteur accessible par deux threads sans synchronisation

class ThreadsConflict { 
      private static int counter = 0; 

      public static void main(String[] args) throws InterruptedException{ 
        Thread t1 = new A(); 
        Thread t2 = new A(); 
        t1.start(); 
        t2.start(); 

        t1.join(); 
        t2.join(); 

        System.out.println(counter); 
      } 

      static class A extends Thread { 
        public void run() { 
          for(int i = 0; i < 10; i++) { 
            counter++; 
          } 
        } 
      } 
    } 

Je peux comprendre pourquoi il sera 10 si elles sont intercalés et l'opérateur ++ sont contradictoires mais comment est-il possible que ce sera moins de 10 ans?

Répondre

1

C'est parce que désentrelacement se produit entre les opérations non atomiques afin counter++ peut être interrompu au milieu, une sorte de:

int tmp = counter; 
/* threads gets interrupted here */ 
counter = tmp + 1; 

Cela peut conduire à des situations de cas de coin comme:

  • thread A lire 0 Thread 0 lit 0 et écrit 1
  • ...
  • fil B 8 lit et écrit 9
  • thread A écrit une
  • fil B lit 1
  • fil Un lit et écrit 1 2
  • fil Un lit et écrit 2 3
  • ...
  • thread A 9 lit et écrit 10
  • thread A terminé
  • fil B écrit 2
  • fil B terminé

esprit que ce soit parce que i est utilisé comme condition pour exactement 10 itérations sont faites, si vous utilisiez directement counter alors vous serez assuré d'avoir au moins 10.

+0

Je vois comment vous avez atteint '2' mais pourquoi est-ce minime? (Juste intéressé) – OldCurmudgeon

+1

Parce qu'il n'y a pas de pire moyen (du point de vue du filetage) que les threads vont s'exécuter. – Tomer

+0

Je l'ai exécuté plusieurs fois avec des résultats compris entre 10 et 20. Cela dépend du nombre de threads dans le système, du thread qui reçoit le processeur et du moment. Une boîte peut complètement finir avant que B ne commence. Bien que votre scénario soit possible, il est hautement improbable. – edharned