2010-09-11 17 views
6

Ich bin neu in Java Threads und Synchronisation.Java synchronisierte Frage

Können sagen, ich habe:

public class MyClass(){ 

    public synchronized void method1(){ 
     //call method2(); 
    } 

    public synchronized void method2(){}; 

} 
  1. Was bedeutet es, wenn ich ein method1() auf einer Instanz-Objekt synchronisiert werden? Wenn ein Thread die Sperre beim Zugriff auf die synchronized method1() erlangte, verhindert es dann, dass andere Threads von demselben Objekt aus auf eine andere synchronized method2() zugreifen?

  2. Nehmen wir ein Thread eine Sperre erlangt, wenn method1 Zugriff(), aber können sagen, daß method1() einen Anruf zu method2() macht die auch synchronized ist. Kann das möglich sein? Ich meine, gibt es irgendwelche Regeln, die verhindern können method1()method2() aufrufen?

Vielen Dank im Voraus.

Antwort

4
  1. See here:

    es ist für zwei Invokationen von synchronisierten Methoden auf dem gleichen Objekt nicht möglich, verschachteln. Wenn ein Thread eine synchronisierte Methode für ein Objekt ausführt, werden alle anderen Threads aufgerufen, die synchronisierte Methoden für denselben Objektblock aufrufen (Ausführung aussetzen), bis der erste Thread mit dem Objekt ausgeführt wird.

  2. Da dieser Thread die Sperre an dem aktuellen Objekt hält, es kann method2() aufrufen, und kein anderer Thread kann.

7
  1. Ja, bedeutet den synchronized Verfahren Modifikator auf einem nicht-statischen Verfahren, dass es den Monitor der Instanz verwendet das Verfahren auf aufgerufen wird, und dies zwischen allen derartigen Verfahren gemeinsam genutzt wird.
  2. Nein - der Thread besitzt bereits den Monitor, so dass es kostenlos ist, andere Blöcke einzugeben, die durch denselben Monitor geschützt sind.
2

Ein Hinweis auf Frage 2, method1() auch in anderen Klassen auch synchronisierte Methoden aufrufen können, die eine Sackgasse führen könnte:

Thread1 Anrufe synchronisiert method1(), die wiederum rufen muss synchronisiert method_b() in AnotherClass Thread2 enthält die Sperre für AnotherClass und führt eine Methode aus, die method1() in der Klasse aufrufen muss, deren Sperre von Thread1 gehalten wird. Beide Threads blockieren die Wartezeit, bis der andere die Sperre freigibt. a Sackgasse.

2

(1) Dies ist äquivalent zu:

public void method1(){ 
    synchronized (this) { 
     ... 
    } 
} 

, damit es auf der aktuellen Instanz synchronisiert. Wenn wir methode2 auf die gleiche Art und Weise umschreiben ...

public void method2(){ 
    synchronized (this) { 
     ... 
    } 
} 

...dann können Sie deutlich sehen, dass sie das gleiche Objekt sperren und daher können andere Threads method1 oder method2 nicht aufrufen, bis method1 seinen synchronized-Block verlässt.

(2) synchronized Blöcke sind reentrant, was bedeutet, dass derselbe Thread andere synchronized Blöcke eingeben kann, die dasselbe Objekt so oft sperren, wie es will. So wie ich es verstehe, erhöht Java jedes Mal, wenn Sie einen synchronized Block eingeben, einen Zähler für das Objekt, mit dem Sie synchronisieren, um 1, und jedes Mal, wenn Sie einen synchronized Block verlassen, wird der Wert verringert. Wenn dieser Zähler 0 erreicht, wird die Sperre aufgehoben.