Java ArrayList从并行线程中删除不存在的对象



最近我在玩信号量和多线程时,我注意到数组列表发生了一些奇怪的事情。更多详细信息:

我有一个单独的私人ArrayList:

public class NewClass{
    private ArrayList list = new ArrayList();
    public void put(Object val){
        list.add(val);
    }
    public void del(Object val){
        list.remove(val);
    }
}

从某个线程中,我试图从中删除元素(在此之前不添加任何内容):

public class SomeClass {
    public static void main(String[] args) throws InterruptedException {
        new SomeClass();
    }
    public SomeClass() throws InterruptedException {
        Thread tr2 = new Thread() {
            @Override
            public void run() {
                NewClass nc = new NewClass();
                for (int i = 0; i < 100; i++) {
                        nc.del(i);
                }
            }
        };
        tr2.start();
    }
}

当线程开始工作时,我没有错误,没有异常等。而如果进行调试,我可以清楚地看到列表.indexOf(val);return-1值-它实际上不存在,但被"移除"了。有人能解释一下这里发生了什么吗?

如果您试图用remove(Object o)方法删除列表中没有的东西,则列表不会抛出异常。它们返回false。

注释太长:

  • NewClass实例不是跨线程共享的,每个实例只能从一个线程访问
  • 在空列表上调用List.remove(int index)没有什么特别的(它返回-1)

就像你说的"玩东西"。

我怀疑你被夹在中间了ArrayList的两种方法。

 public E remove(int index) // throws exception 
and 
 public boolean remove(Object o) // doesn't throws exception

当您通过it线程进行访问时,实际上是像引用一样将其作为对象进行传递。它实际上调用了remove(Object o)方法,该方法不会抛出异常。

而我认为在玩单线程程序时,你直接调用

list.remove(int)///方法,该方法实际抛出IndexOutOfBoundsException。

这只是我的假设,因为您还没有提供它抛出异常的代码

当您调用remove时,列表将变得比以前更短。你认为你的循环代码是对的吗?总长度不再是100。

最新更新