Я пытаюсь убедить себя, что действия, предпринятые в предложении finally
, происходят до возврата функции (в смысле согласованности памяти).Из спецификации JVM ясно, что в потоке программный порядок должен приводить в действие до того, как - если a происходит b в программном порядке, тогда a происходит раньше, чем b .
Однако я не видел ничего явно заявляющего, что наконец происходит до возврата, так что же?Или есть какой-то способ, которым компилятор может переупорядочить предложение finally
, так как оно просто ведет журнал.
Пример мотивации: у меня один поток извлекает объекты из базы данных и помещает их в ArrayBlockingQueueдругая нить снимает их.У меня есть несколько блоков try
- finally
для определения времени события, и я вижу после эффектов до оператора журнала
Поток 1:
public Batch fetch() {
try {
log("fetch()+");
return queryDatabase();
}
finally {
log("fetch()-");
}
...
workQueue.put(fetch());
Тема 2:
log("take()+");
Batch b = workQueue.take();
log("take()-");
К моему большому удивлению, это распечатывается в неожиданном порядке.Хотя да, операторы журналирования в разных потоках могут появляться не по порядку, разница во времени составляет не менее 20 мс.
124 ms : take()+
224 ms : fetch()+
244 ms : take()-
254 ms : fetch()-
Обратите внимание, что это не совсем тот же вопрос, что и , наконец, превосходитвернуться .Я не спрашиваю, что будет возвращено, а о согласованности памяти и порядке выполнения.