背景
我想了解为什么一段代码片段不会抛出NullPointerException异常。
源代码
考虑以下代码:
public class Agent {
public List files = new ArrayList();
public void deliver() {
if( files != null && files.iterator().hasNext() ) {
File file = (File)files.iterator().next();
}
files = new ArrayList();
}
}
deliver
方法会被重复调用,而以下代码则在另一个线程中运行: public void run() {
agent.files = null;
}
只有一个代理
实例。
问题
永远不会抛出NullPointerException。
然而,当deliver
方法暂停时,即使是0毫秒,也会如预期地抛出NullPointerException:
public void deliver() {
if( files != null ) {
Thread.currentThread().sleep( 0 );
if( files.iterator().hasNext() ) {
File file = (File)files.iterator().next();
}
}
files = new ArrayList();
}
我的理解是,在检查files == null
和调用files.iterator().hasNext()
之间存在一种竞态条件。但实际上,如果没有引入暂停(即将空检查与后续方法调用分开),我无法触发竞态条件。
问题
为什么第一个deliver
方法在同一语句中组合空检查和使用时不会抛出异常?
javap
输出,以便围绕竞态条件区域进行分析? - nanofarad