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
Ich schätze, du sollst den Monitor auch im Ausnahmefall loslassen. –
Soll der Monitor unendlich oft ausgelöst werden, auch wenn klar ist, dass das nicht möglich ist? Ha! – aboveyou00
Wann ist klar, dass Sie nicht können? Es gibt eine wichtige Bedingung, dass Sperren und Freischaltungen immer ausgeglichen sind. –