2013-02-27 7 views
7

Blick auf die Java Virtual Machine Specification und kompilierten Code sagt uns, wie "synchronized" Blöcke in Java implementiert sind. Der folgende Code:JVM Synchronisierte schließlich Blöcke

public void testSync() 
{ 
    Object obj = getSomeObject(); 
    synchronized (obj) { doSomething(); } 
} 

... entspricht in etwa dieser Pseudo-Code:

public void testSync() 
{ 
    Object obj = getSomeObject(); 
    Object __temp = obj; 
    monitorenter __temp; 
    try { doSomething(); } 
    finally { monitorexit __temp; } 
} 

... mit einer Ausnahme.

Aus irgendeinem Grund werden in der Ausnahmetabelle zwei Handler angezeigt. Zum Beispiel:

Exception table: 
    from to target type 
     12 20 23 any 
     23 25 23 any 

Der erste Handler ist, wo ich es erwarten, aber der zweite Handler ist eigentlich für den finally-Block des ersten Handler, und wenn es eine Ausnahme abfängt führt sie den gleichen Handler. Man könnte dies schlecht in der folgenden Art und Weise visualisieren:

try { doSomething(); } 
finally { beginTry: try { monitorexit __temp; } finally { goto beginTry; } } 

Weiß jemand, warum das so ist? Wenn es nur der finally-Block wäre, wäre der zweite Eintrag in der Tabelle nicht vorhanden. Außerdem kann ich keinen möglichen Grund sehen, den finally Block erneut ausführen zu wollen, wenn er bereits eine Ausnahme auslöst.

Danke, Brandon

+2

Ich schätze, du sollst den Monitor auch im Ausnahmefall loslassen. –

+0

Soll der Monitor unendlich oft ausgelöst werden, auch wenn klar ist, dass das nicht möglich ist? Ha! – aboveyou00

+0

Wann ist klar, dass Sie nicht können? Es gibt eine wichtige Bedingung, dass Sperren und Freischaltungen immer ausgeglichen sind. –

Antwort

2

Wenn es eine Wahl immer und immer wieder zwischen seinem erfolglosen Versuch, den Monitor zu lösen, und Verfahren ohne Loslassen, werden beide Alternativen zu einem Deadlock führen; nur wenn Sie ohne Freigabe fortfahren, dann passiert der Deadlock erst, wenn das nächste Mal versucht wird, den Monitor zu erfassen, und dieses Problem kann weit entfernt vom ursprünglichen Fehler sein. Auch der Versuch, den Monitor freizugeben, kann eventuell funktionieren, während der Monitor nicht freigegeben wird, ist ein gewisses Desaster. Also solltest du es besser versuchen.

+0

Wenn Sie Sagen wir es so, es macht viel mehr Sinn. Ich denke ich war einfach in der falschen Einstellung. Vielen Dank! – aboveyou00

+0

@ aboveyou00: Es bringt dich zum Nachdenken. Es muss Spaß machen, dieses Zeug zu implementieren und zu wissen, dass es auf allen Arten von Prozessoren funktionieren muss. –

+0

Ja, auf diese Weise ist sogar eine Endlosschleife besser, als den Monitor unveröffentlicht zu lassen. – maaartinus