返回是否最终“发生”?
我试图说服自己,子句中执行的操作发生在函数返回之前(在内存一致性意义上)。从JVM规范中可以清楚地看出,在线程中,程序顺序应该驱动发生在b之前的关系 - 如果a在程序顺序中发生b,那么a发生在b之前。finally
但是,我没有看到任何明确说明最终发生在返回之前的事情,所以呢?或者,是否有某种方法可以使编译器对子句重新排序,因为它只是日志记录。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()-
请注意,这与最终胜过回归的问题并不完全相同。我不是在问将返回什么,而是关于内存一致性和执行顺序。