2012-06-03 9 views
12

Gibt es einen Unterschied zwischen:lock.lock() vor versuchen

private Lock lock = new ReentrantLock(true); 

public void getIn (int direction) throws InterruptedException { 

    lock.lock(); 
    try { 
     ... 

und

... 

public void getIn (int direction) throws InterruptedException { 

     try { 
      lock.lock(); 
      ... 

Compilation glatt geht und auch das Programm funktioniert (ich meine die gleiche Ausgabe)

Sollte ich lock.lock() setzen; vor oder nach versuchen ...

Danke für jede Hilfe

+1

Welche Klasse ist 'lock'? – Thor

+1

Was wird gefangen? Wenn Sie später 'ExceptionThatLockCannotThrow' fangen, gibt es keinen wirklichen Unterschied zwischen ihnen – amit

+0

Ein paar Statements vorher: private Lock lock; und dann lock = new ReentrantLock (true); danke ... der Entriegelungsvorgang ist am Ende erledigt; endlich} lock.unlock(); – 9628001

Antwort

0

Im ersten Fall: wenn die lock.lock() wirft InterruptedException, getIn wird es verwalten. Aber für jede andere Ausnahme, wäre es eine Ausnahme auslösen, die getIn nicht Griffe: Runtime Exception

Im zweiten Fall: Neben InterruptedException, der try-catch Block auch eine gewisse Ausnahmebehandlung tut, die Sie hier nicht gezeigt haben. Dies sollte kleinere Ausnahmen auslösen, da der innere Block auch einige Ausnahmen erfasst.

Die gesamte Ausführung hängt davon ab, welche Ausnahmen lock.lock() wirft?

+0

Die Methode ['lock()'] (http://download.java.net/jdk8/docs/api/java/util/concurrent/locks/ReentrantLock.html#lock--) löst InterruptedExceptions nicht aus.Der Block in der "getIn" -Methode ist eigentlich ein 'try-finally'-Block, kein' try-catch'-Block. –

9

Angenommen, dass lock ein ReentrantLock ist, dann macht das keinen wirklichen Unterschied, da lock() keine geprüften Ausnahmen auslöst.

Die Java-Dokumentation verlässt jedoch lock() außerhalb des try Blocks im ReentrantLock Beispiel. Der Grund dafür ist, dass eine unmarkierte Ausnahme in lock() nicht zu unlock() falsch aufgerufen werden sollte führen. Ob die Korrektheit bei einer ungeprüften Ausnahme von lock() von allen Dingen ein Problem ist, das ist eine andere Diskussion überhaupt.

Es ist eine gute Kodierungspraxis im Allgemeinen Dinge wie try Blöcke so feinkörnig wie möglich zu halten.

4

Die try-Anweisung enthält auch:

} finally { 
    lock.unlock(); 
} 

Das heißt, wenn Sie lock.lock() nach try platzieren, von lock.lock() geworfen Ausnahmen lock.unlock() verursachen würde, was falsch ist, weil Sperre nicht erhalten wurde, und Entriegelung verursachen würde eine weitere Ausnahme. Also die erste Variante ist richtig. Um Ausnahmen zu behandeln, die von lock.lock() ausgelöst werden, müssen Sie eine andere try-Anweisung verwenden.

9

Wenn Fall Nr. 1, in finally können Sie einfach unlock() sagen. Im Fall No2 müssen Sie prüfen, ob Sie das Schloss vor unlock() halten, sonst erhalten Sie IllegalMonitorStateException