0

Im folgenden Code, nachdem ein Thread die increment-Methode ausführt, gibt er den Wert 2 an die Konsole aus.Wenn der Wert nicht 1 sein sollte erhöht es um 1?Warum erhöht der folgende Code den Wert mit 2 anstelle von 1? (Neu in Java)

class TestSync implements Runnable { 
private int balance; 

public void run() { 

    for(int i = 0; i < 50; i++){ 

     increment(); 
     System.out.println(Thread.currentThread().getName() + " balance after increment is " +balance); 
    } 

} 

private synchronized void increment() { 

    int i = balance; 
    balance = i + 1; 
    // System.out.println(balance); 
} 

}

public class TestSyncTest {

public static void main(String[] args) { 

    TestSync job = new TestSync(); 
    Thread a = new Thread(job); 
    Thread b = new Thread(job); 
    a.setName("Thread A"); 
    b.setName("Thread B"); 

    a.start(); 
    b.start(); 

} 

}

+1

Was passiert, wenn beide Threads den Wert erhöhen, bevor einer von ihnen wird aus dem Wert drucken? – tkausl

+0

Versuchen Sie, das vorhandene 'System.out.println' zu kommentieren und das Kommentarzeichen zu entfernen, das Sie jetzt auskommentiert haben. –

+0

Können Sie meine Antwort bitte überprüfen? – KeLiuyue

Antwort

0

Da der Code in der Schleife ist .Und balance ist globale Daten.

In der ersten Schleife balance ist der Wert 1.

for (int i = 0; i < 50; i++) { 

     increment(); 
     System.out.println(Thread.currentThread().getName() + " balance after increment is " + balance); 
} 

OUTPUT

//   i  balance 
// first 0   1 
// second 1   2 
// third 2   3 
// ... 
+0

Ich verstehe die Logik, die Sie versuchen zu erklären. Die print-Anweisung gibt die Werte beginnend mit 2 statt 1 aus, das ist was mich verwirrt. –

+0

Sie können für es debuggen. Machen Sie es einfacher für Sie zu verstehen – KeLiuyue

0

Ihre Inkrementmethode synchronisiert ist, aber der Rest wird durch die variable Threads gemeinsam genutzt. Nachdem die ersten Threadaufrufe inkrementiert wurden, kann der andere Thread vor dem Drucken des Kontostands Inkrement aufrufen. Setzen Sie die print-Anweisung in die increment-Methode.

0

Beide Threads teilen sich das gleiche Objekt. Die einzige synchronisierte Methode erhöht den Wert von i, aber es gibt keine Garantie für die Reihenfolge, in der sie den Wert drucken, und nicht für den Status, in dem sie gedruckt werden.

Wenn Sie möchten, dass jede Methode ihren Wert nach dem Inkrement ausgibt, entfernen Sie das Kommentarzeichen sysout aus der synchronisierten Methode, und entfernen Sie sie aus run().

Wenn Sie erwarten, dass alle Threads abgeschlossen sind, bevor Sie drucken, müssen Sie Thread.join() verwenden.

Hier ist ein kurzes Beispiel:

class TestSync implements Runnable { 
    private int balance; 

    public void run() { 

     for(int i = 0; i < 50; i++){ 
      increment(); 
     } 

    } 

    private synchronized void increment() { 

     int i = balance; 
     balance = i + 1; 
    } 

    public void printBalance() ´{ 
     System.out.println("Balance: " + balance); 
    } 
} 

public static void main(String[] args) { 

    TestSync job = new TestSync(); 
    Thread a = new Thread(job); 
    Thread b = new Thread(job); 
    a.setName("Thread A"); 
    b.setName("Thread B"); 

    a.start(); 
    b.start(); 

    try { 
     System.out.println("Wait for threads to finish."); 
     a.join(); 
     b.join(); 
    } catch (InterruptedException e) { 
     System.out.println("Interruption waiting for threads to finish."); 
    } 
    a.printBalance(); // either method will print the same value. 
} 
Verwandte Themen