Я пытаюсь убедить себя, что действия, выполняемые в предложении 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()-
Обратите внимание, что это не совсем тот же вопрос, что и наконец, возвращает козырь. Я не спрашиваю, что будет возвращено, но вместо этого о согласованности памяти и порядке выполнения.