gpt4 book ai didi

java - 为什么这段代码不抛出 NullPointerException?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:27:54 34 4
gpt4 key购买 nike

背景

我想了解为什么一段代码不会抛出 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;
}

只有一个agent实例。

问题

永远不会抛出 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() 之间存在竞争条件。实际上,我无法在不引入暂停的情况下触发竞争条件(即,将空检查与后续方法调用分开)。

问题

当 null 检查和用法组合在同一语句中时,为什么第一个 deliver 方法不会抛出异常?

最佳答案

两件事:

  1. Thread.sleep(0) 仍然暂停执行(可能超过 0 毫秒)。基本上,即使是 0 sleep 也会导致该线程的执行短暂停止,然后重新启动。这使另一个线程有机会运行并完成,这就是您能够触发竞争条件的原因。

  2. 文件应该是volatile,否则允许 JVM 以您可能永远不会注意到它正在改变的值的方式进行优化,因为它认为它不需要保持一致性在线程之间。

关于java - 为什么这段代码不抛出 NullPointerException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19737490/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com