2016-10-08 3 views
5

Synchronisation funktioniert einwandfrei in diesem Code:Warum funktioniert die Synchronisation im zweiten Code nicht?

class PrintNumbers { 
     synchronized public void display() { 
      System.out.println("in display"); 
      for (int i = 0; i < 3; i++) { 
       System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.getMessage(); 
       } 
      } 
      System.out.println("out of display"); 
     } 
    } 

    class MyThread implements Runnable { 
     Thread t; 
     PrintNumbers printNumbers; 

     MyThread(PrintNumbers printNumbers, String s) { 
      this.printNumbers = printNumbers; 
      t = new Thread(this,s); 
      t.start(); 
     } 

     public void run() { 
      printNumbers.display(); 
     } 
    } 

    class SyncExample { 
     public static void main(String[] args) { 
      PrintNumbers printNumbers = new PrintNumbers(); 

      new MyThread(printNumbers, "My Thread 1"); 
      new MyThread(printNumbers, "My Thread 2"); 
     } 
    } 

Ausgang:

in display 
Thread name : My Thread 1 i= 0 
Thread name : My Thread 1 i= 1 
Thread name : My Thread 1 i= 2 
out of display 
in display 
Thread name : My Thread 2 i= 0 
Thread name : My Thread 2 i= 1 
Thread name : My Thread 2 i= 2 
out of display 

aber nicht in diesem Code:

class PrintNumbers { 
     synchronized public void display() { 
      System.out.println("in display"); 
      for (int i = 0; i < 3; i++) { 
       System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.getMessage(); 
       } 
      } 
      System.out.println("out of display"); 
     } 
    } 

    class MyThread implements Runnable { 
     Thread t; 
     PrintNumbers printNumbers; 

     MyThread(String s) { 
      this.printNumbers = new PrintNumbers(); 
      t = new Thread(this,s); 
      t.start(); 
     } 

     public void run() { 
      printNumbers.display(); 
     } 
    } 

    class SyncExample { 
     public static void main(String[] args) { 
      new MyThread("My Thread 1"); 
      new MyThread("My Thread 2"); 
     } 
    } 

Ausgang:

in display 
Thread name : My Thread 1 i= 0 
in display 
Thread name : My Thread 2 i= 0 
Thread name : My Thread 1 i= 1 
Thread name : My Thread 2 i= 1 
Thread name : My Thread 2 i= 2 
Thread name : My Thread 1 i= 2 
out of display 
out of display 

Ich kann nicht verstehen, welchen Unterschied wrt Synchronisation macht, um PrintNumbers in der Runable MyThread und in der SyncExample-Klasse zu initialisieren. Bitte erkläre.

+0

nicht statische synchronisierte Methoden synchronisieren auf 'this'. – tkausl

+0

2. Sie benötigen die "Anzeige" -Methode statisch, sie sperren 2 Objekte. – passion

+1

Sie verwenden das Differenzobjekt von PrintNumbers und die Sperre ist auf Objektebene. Deshalb erhalten Sie unterschiedliche Ergebnisse. – cody123

Antwort

5

Ich kann nicht verstehen, welchen Unterschied wrt Synchronisation macht, um PrintNumbers in der Runable MyThread und in der SyncExample-Klasse zu initialisieren.

Es tut es nicht. Was ist Angelegenheit ist, dass in Ihrem ersten Beispiel haben Sie nur einePrintNumbers Instanz, die beide Threads teilen. Aber in Ihrem zweiten Beispiel haben Sie zwei separate PrintNumbers Instanzen, eine für jeden Thread.

Da PrintNumbers#display auf der Instanz synchronisiert (synchronized Instanzmethoden synchronisieren auf this), so synchronisiert sich nur innerhalb der Instanz, nicht über mehrere Instanzen. Wenn sich beide Threads eine Instanz teilen, werden die beiden Aufrufe von display serialisiert. Wenn die Threads jedoch jeweils eine eigene Instanz haben, befinden sich die beiden Aufrufe von display auf separaten Instanzen, und daher gibt es keine Serialisierung der Aufrufe, sie können sich überlappen.

4

Da im zweiten Code hat jeder Thread seine eigenen PrintNumbers Objekt, so dass sie parallel arbeiten. In der ersten teilen sie sich das einzelne PrintNumbers Objekt und arbeiten synchron damit.

PS. Denken Sie daran, dass synchronized für nicht statische Methoden die Synchronisation auf Objekt (für statische Methoden auf Klasse) macht.

3

Es funktioniert in beiden Fällen wie es sollte. Der Unterschied besteht darin, dass Sie im ersten Fall ein einzelnes Objekt haben, das synchronisiert wird. In der zweiten haben Sie zwei. Sie werden beide nur einmal aufgerufen, so dass sie perfekt synchronisiert sind.

synchronized funktioniert nicht zwischen Objekten, nur innerhalb eines.

Verwandte Themen