加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-15 03:09:34 所属栏目:Java 来源:网络整理
导读:背景 我想了解为什么一段代码不会抛出NullPointerException. 源代码 请考虑以下代码: public class Agent { public List files = new ArrayList(); public void deliver() { if( files != null files.iterator().hasNext() ) { File file = (File)files.ite
背景

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

传递方法被重复调用,而以下代码在一个单独的线程中运行:

public void run() {
    agent.files = null;
  }

只有一个代理程序实例.

问题

永远不会抛出NullPointerException.

但是,当传递方法暂停时,即使是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();
  }

我的理解是,理论上,在检查文件== null和调用files.iterator().hasNext()之间存在竞争条件.在实践中,我不能在不引入暂停的情况下触发竞争条件(即,从后续方法调用中拆分空检查).

为什么第一个传递方法在同一语句中组合空检查和使用时不会抛出异常?

解决方法

两件事情:

> Thread.sleep(0)仍然停止执行(可能超过0毫秒).基本上,即使是0睡眠也会导致该线程上的执行暂时停止,然后重新启动.这使得另一个线程有机会运行和完成,这就是为什么你能够触发竞争条件.>文件应该是易失性的,否则允许JVM以这样的方式进行优化,使得您可能永远不会注意到它正在改变值,因为它不认为它需要保持线程之间的一致性.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读