2015-10-29 1 views
0

Premier code:Java threading problème de blocage

public class H extends Thread {

String info = ""; 

public H (String info) { 
    this.info = info; 
} 
public synchronized void run() { 
    try { 

    while (true) { 
     System.out.println(info); 
     notify(); 
     wait(); 
    } 
    } catch (Exception e) {} 
} 
public static void main (String args []) { 
    new H("0").start(); 
    new H("1").start(); 
} 

}

second code:

public class H extends Thread {

String info = ""; 

static Object o = new Object(); 
public H (String info) { 
    this.info = info; 
} 
public synchronized void run() { 
    try { 

    while (true) { 
     System.out.println(info); 
     o.notify(); 
     o.wait(); 
    } 
    } catch (Exception e) {} 
} 
public static void main (String args []) { 
    new H("0").start(); 
    new H("1").start(); 
} 

}

Si le premier code Je suis d'accord, il passe en état de blocage comme méthode d'exécution synchronisée ne sera jamais déverrouiller. Mais pourquoi dans le second code, si la méthode d'exécution entière est synchronisée sans objet, j'essaie d'attendre et de notifier l'objet o, il faut soit aller dans l'interblocage, soit exécuter le code continuellement (à cause de while (true)), mais le code existe avec le code de sortie 0. Quelqu'un peut-il m'aider à ce sujet. Merci d'avance !!!!

+0

Dans le premier code n'y a pas de fil contenant les moniteurs verrouillage qui va réveiller le fil d'attente. Dans la seconde, printStackTrace() masque cette erreur: java.lang.IllegalMonitorStateException Voir le doc API pour les méthodes wait et nofity dans la classe Object. – NormR

Répondre

1

Le deuxième exemple de code que vous avez est de ne pas faire ce que vous pensez qu'il est.

Vous venez d'attraper Exception et de l'enterrer, sans aucune information. Lorsque o.notify() est appelé, il lancera une IllegalMonitorStateException, brisant donc hors des boucles While et la cause de votre programme pour sortir avec le code de retour 0.

Pour appeler correctement informer, le cours d'exécution fil doit avoir une serrure sur l'objet que vous notifiez.

Dans l'exemple 1, la méthode run() synchronisée maintient un verrou sur this, vous pouvez donc faire this.notify().

Toutefois, dans le second exemple, il n'y a pas de synchronisation sur l'objet o lorsque vous l'informez, provoquant ainsi theIllegalMonitorStateException.

Voici une copie "fixe" de la deuxième version du code. Cette boucle de volonté en alternance à l'infini entre l'impression 0 et de 1, ce qui je pense est ce que vous attendiez:

public class H extends Thread{ 
    String info = ""; 

    static Object o = new Object(); 
    public H (String info) { 
     this.info = info; 
    } 

    public synchronized void run() { 
     try { 

     while (true) { 
      System.out.println(info); 
      synchronized(o){ 
       o.notify(); 
       o.wait(); 
      } 
     } 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 
    public static void main (String args []) { 
     new H("0").start(); 
     new H("1").start(); 
    } 
} 
+0

Exactement, mais il ne lance même pas IllegalMonitorStateException –

+0

Qu'entendez-vous par "il"? –