2009-08-14 6 views
1

Können nicht synchronisierte Methoden, die von synchronisierten Methoden aufgerufen werden, einen Thread blockieren?Java-Thread blockieren

public synchronized void foo(){ 
someStuff(); 
someMoreStuff(); 
bar(); 
} 

public void bar(){ 
//... does some things 
} 

Wenn ein Thread foo ausgeführt wird() ist es trotzdem, dass Bar zu gewährleisten() wird, bevor der Thread schläft genannt werden?

TIA

Antwort

3

Ein Thread kann immer vorbelegt werden (es gibt keine Möglichkeit, dass in Java zu verhindern), aber kein anderer Thread in der Lage, die Sperre auf das gleiche Objekt vor foo kehrt zu erwerben.

Beachten Sie, dass ein Thread "Verlieren der CPU" ist nicht das, was normalerweise mit "Blockieren" gemeint ist - normalerweise wird ein Anruf blockiert, wenn es auf etwas anderes warten muss. Zum Beispiel:

  • aus einem Stream-Blöcken Lesen, bis einige Daten verfügbar
  • eine Sperre blockiert Acquiring, bis die Sperre verfügbar (oder das Ende des Datenstroms erreicht wird) ist

Diese sind sehr anders als gerade aus der Zeitscheibe zu laufen.

+0

Danke für die Klarstellung, das Zeug ist nicht trivial :) – javamonkey79

1

Fragen Sie, ob es eine Möglichkeit gibt, sicherzustellen, dass die Java VM die CPU nicht übernimmt und einen anderen Thread ausführen lässt? Sie könnten die Thread-Priorität auf "Hoch" setzen, aber dies würde immer noch keine Garantie bieten.

Kein anderer Thread kann Ihre "foo" -Methode aufrufen, obwohl Sie nicht über die CPU verfügen. Ebenso würde das Synchronisieren von "bar" verhindern, dass es aufgerufen wird, bis Ihr Aufruf an "foo" abgeschlossen wurde (da Sie die Sperre für den gesamten Zeitraum der "foo" -Methode besitzen).

1

Die Frage scheint zu sein, wenn andere Threads bar() frei aufrufen können, während ein Thread die Sperre für ein Objekt während der Ausführung von foo() hält. Und speziell, wenn zwei oder mehr Threads gleichzeitig bar() ausgeführt werden können.

Und die Antwort ist, dass jeder Thread bar() zu jeder Zeit ausführen kann, also ja, es kann mehr als einen Thread running bar() zu jedem Zeitpunkt geben.