2017-09-29 3 views
0

Je suis tellement confus au sujet de ce code:Pourquoi System.out.println affecte l'ordre d'exécution dans Java?

public class SynchronizedTest implements Runnable { 

private int b = 100; 

public synchronized void test01() throws InterruptedException { 
    b = 1000; 
    Thread.sleep(5000); 
} 

public synchronized void test02() throws InterruptedException { 
    b = 2000; 
    Thread.sleep(2500); 
    //System.out.println("test02 end !"); 
} 

@Override 
public void run() { 
    try { 
     test01(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

public static void main(String[] args) throws InterruptedException { 
    SynchronizedTest test = new SynchronizedTest(); 
    Thread thread01 = new Thread(test); 
    thread01.start(); 
    test.test02(); 
    System.out.println(test.b); 
} 

} 

Si je ne pas ajouter ce code System.out.println("test02 end !"); dans le code ci-dessus. Le résultat de l'opération sera imprimé 1000, mais si le code y est ajouté, le résultat de l'opération deviendra "test02 end!" et 2000;

Je ne sais pas pourquoi, comment l'expliquer?

+0

System.out.printline() n'est pas sécurisé par les threads https://stackoverflow.com/questions/9459657/synchronization-and-system-out-println – User

+0

La sécurité des threads n'est-elle pas assurée? le code source ajouter sychnroized maintenant public void println (int x) { synchronisé (this) { impression (x); newLine(); } } –

+0

Je pense que le problème est ordre d'exécution, Athought Sout n'est pas threadsafe, il n'y a pas d'effets pour le code. –

Répondre

0

Ceci est certainement lié à la façon dont le compilateur planifie les instructions. La valeur de b est en cours de modification, mais le compilateur a planifié l'instruction d'impression avant d'appeler la fonction test02.

SynchronizedTest test = new SynchronizedTest(); 
Thread thread01 = new Thread(test); 
thread01.start(); 
System.out.println(test.b); 
System.out.println(test.b); 
test.test02(); 
System.out.println(test.b); 

J'ai essayé l'ordre ci-dessus, et la sortie était

100 
1000 
2000 

Cela confirme aussi mon argument. Cela ne se produit pas si vous décommentez l'instruction print car le compilateur déduit maintenant qu'il doit imprimer le texte à l'intérieur de la fonction test02 et ne modifie donc pas l'ordre de l'exécution.

Cependant je ne suis pas sûr pourquoi le compilateur change l'ordre dans le premier cas.

+0

Mon résultat d'opération de code pas même avec votre ... impression 100,100,2000 .. je pense qu'il n'y a aucun moyen d'imprimer 1000, bacause quand test02 exécuté, l'objet SynchronizedTest est verrouillé, seulement test02 fin il y aura test01. Le temps total est de 7,5 secondes –

+0

Je pense que cela dépend complètement du compilateur. J'ai reçu 1000 exemplaires. C'est quelque chose que nous ne pouvons pas complètement comprendre sans savoir comment le compilateur a été construit. –