最近我在玩信号量和多线程时,我注意到数组列表发生了一些奇怪的事情。更多详细信息:
我有一个单独的私人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。