2012-09-13 5 views
1

Dans le code suivant, je m'attendais à ce que l'un des deux threads entre dans la fonction halt() et interrompe le programme. Mais il semble que les deux threads entrent dans la fonction synchronized halt(). Pourquoi cela pourrait-il arriver?compréhension du fonctionnement du mot-clé synchronisé

package practice; 

class NewThread implements Runnable { 
    String name; // name of thread 
    Thread t; 
    boolean suspendFlag; 

    NewThread(String threadname) { 
    name = threadname; 
    t = new Thread(this, name); 
    System.out.println("New thread: " + t); 
    suspendFlag = false; 
    t.start(); // Start the thread 
    } 

    // This is the entry point for thread. 
    public void run() { 
    try { 
     for(int i = 15; i > 0; i--) { 
     System.out.println(name + ": " + i); 
     Thread.sleep(200); 
     Runtime r = Runtime.getRuntime(); 
     halt(); 
     } 
    } catch (InterruptedException e) { 
     System.out.println(name + " interrupted."); 
    } 
    System.out.println(name + " exiting."); 
    } 

    synchronized void halt() throws InterruptedException 
    { 
     System.out.println(name + " entered synchronized halt"); 
     Runtime r = Runtime.getRuntime(); 
     Thread.sleep(1000); 
     r.halt(9); 
     System.out.println(name + " exiting synchronized halt"); // This should never execute 
    } 
} 

class Practice{ 
    public static void main(String args[]) { 
    NewThread ob1 = new NewThread("One"); 
    NewThread ob2 = new NewThread("Two"); 

    // wait for threads to finish 
    try { 
     System.out.println("Waiting for threads to finish."); 
     ob1.t.join(); 
     ob2.t.join(); 
    } catch (InterruptedException e) { 
     System.out.println("Main thread Interrupted"); 
    } 

    System.out.println("Main thread exiting."); // This should never execute 
    } 
} 
+3

Ces deux objets distincts ne sont-ils pas? Si je comprends bien votre code, chaque thread s'exécute sur son propre objet. – kosa

Répondre

2

La synchronisation est effectuée sur chaque objet. Si vous avez 2 objets, 2 threads peuvent entrer simultanément dans la méthode halt(). Vous pouvez rendre la méthode statique pour atteindre ce que vous voulez. En le rendant statique, le verrou sera placé sur l'objet Class correspondant (NewThreadOne.class) qui est unique en ce qui concerne le nombre d'instances de NewThreadOne.

7

synchronisé ne verrouille pas une méthode, il verrouille un objet

Vous avez une méthode mais deux objets. Chaque thread verrouille son propre objet et appelle halt().

1

Vous avez utilisé 2 objects pour 2 threads comme monitor lock ....

Ainsi, votre code fonctionne très bien, avec chaque fil l'accès à la serrure de son propre objet pour accéder à la méthodehalt() ....

en synchonized keyword, vous atteindre la serrure d'un objet, par lequel le fil obtient un accès à la synchronized methods or atomic statements dans cette classe ......

1

La méthode synchronized utilise ceci pour le verrouillage. Dans votre cas, vous avez 2 objets différents, car vous construisez 2 instances de threads, donc vous ne verrouillez pas sur le même objet. Afin d'avoir le comportement de synchronisation que vous attendiez, vous devez utiliser la méthode haltstatic.

1

Il n'est pas recommandé d'utiliser un objet String comme verrou dans le bloc synchronisé java car string est un objet immuable et une chaîne littérale et une chaîne interne est stockée dans le pool de chaînes. Par conséquent, si une autre partie du code ou une bibliothèque tierce utilisait la même chaîne comme verrouillé, ils seraient tous deux verrouillés sur le même objet, même s'ils ne sont pas liés, ce qui pourrait entraîner un comportement inattendu et de mauvaises performances. au lieu de l'objet String il est conseillé d'utiliser new Object() pour la synchronisation en Java sur le bloc synchronisé.

Questions connexes