1

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

我有一些带有单个私有 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();
    }
}

当线程开始工作时 - 我没有错误,没有异常等。而如果调试,我可以清楚地看到 list.indexOf(val); 返回 -1 值 - 它实际上不存在,而是被“移除”。谁能解释这里发生了什么?

4

4 回答 4

2

如果您尝试使用 remove(Object o) 方法删除不在列表中的内容,列表不会引发异常。他们返回错误。

于 2013-07-11T11:53:17.693 回答
0

就像你说的“玩弄东西”。

我怀疑你被 ArrayList 的两种方法所困。

 public E remove(int index) // throws exception 

and 

 public boolean remove(Object o) // doesn't throws exception

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

虽然我认为在玩单线程程序时你直接调用

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

这只是我的假设,因为您没有提供引发异常的代码

于 2013-07-11T15:11:34.863 回答
0

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

于 2013-07-12T08:39:48.033 回答
0

评论太长了:

  • 您的NewClass实例不会跨线程共享,并且每个实例只能从一个线程访问。
  • 调用List.remove(int index)一个空列表没有什么特别的(它返回-1)。
于 2013-07-11T12:04:39.730 回答