我们怎样才能获得NPE,竞争条件

St.*_*rio 5 java multithreading

我在接受采访时被问到以下问题.给定以下代码,如果方法adddoAction多个线程调用,我们如何NullPointerException在打印时获得toString?**

public class Test{
     private List<Object> obj = new ArrayList<Object>();

     public void add(Object o){
           obj.add(o);
     }

     public void doAction(){
           for(Object o: obj){
                 System.out.println(o.toString()); // maybe NPE, why?
           }
     }

}
Run Code Online (Sandbox Code Playgroud)

切断所有其他多线程问题.

Sol*_*low 7

首先,让我们改变变量的名称; List<Object> list=new ArrayList<>();因为"obj"对于引用a的变量来说是一个非常可怕的名称List.

好的,当程序调用时list.add(o);,可能需要增长数组.这意味着它必须:

  1. 分配一个新的,更大的数组,其成员都将被初始化为null,和
  2. 将元素从旧数组复制到新数组.

如果线程A正在做的是,虽然在同一时间线程B调用iterator.next(),线程B可能最终读取null甚至新的数组值之后线程A已经被复制的对象引用到阵列的该成员.

记住:当线程访问没有同步的内存时,读者线程有可能看到变量/字段/数组成员的更新发生的顺序与写入线程实际执行它们的程序顺序不同.