我正在尝试调用我关于核心Java和多线程的概念。当读一些书时,我发现 下面的代码可能会抛出ArrayIndexOutOfBoundsException
如果矢量以某种方式被另一个线程访问。在访问元素时访问向量中的异常
for (int i = 0; i < vector.size(); i++){
doSomething(vector.get(i));
}
我真的尝试了很多,但无法弄清楚如何? 任何人都可以帮助我。
我正在尝试调用我关于核心Java和多线程的概念。当读一些书时,我发现 下面的代码可能会抛出ArrayIndexOutOfBoundsException
如果矢量以某种方式被另一个线程访问。在访问元素时访问向量中的异常
for (int i = 0; i < vector.size(); i++){
doSomething(vector.get(i));
}
我真的尝试了很多,但无法弄清楚如何? 任何人都可以帮助我。
Vector具有所有字段同步。在这种情况下,我们执行诸如获取vertor尺寸的操作,而不是稍后尝试访问i
元素。它们都是同步化的,但它们是按时分布的,我们得到的vertor.size()
和vector.get(i)
之间没有同步,所以我们当前的线程可以被挂起,并且矢量可以被另一个线程修改,因此向量的大小可能会改变。例如:
public class TestClass {
private static final Vector vector = new Vector();
public static void iterate() {
for (int i = 0; i < vector.size(); i++) {
doSomething(vector.get(i));
}
}
public static void main (String... args) {
//initialize vector and fill it
new Thread(new Runnable() {
@Override
public void run() {
iterate();
}
}, "A").start();
new Thread(new Runnable() {
@Override
public void run() {
vector.clear();
}
}, "B").start();
}
private static void doSomething(Object object) {
//DO SMTHNG.
}
}
在这种情况下,而线程A
将遍历向量螺纹B
可以清除它,因此i
可以比新载体的规模以上(在这种情况下为0)。解决这个问题的最简单方法是用synchronized (vector) {...}
块覆盖iterate()
方法体或使用更复杂的方法。
非常感谢。 我明白了。正如我在问题评论中提到的那样,我一直认为代码本身可能导致异常。 – daksh
仅凭这个代码,就不可能说。 “doSomething”做什么?有没有其他线程可以并行访问'vector'? –
如果另一个线程在处理它时删除了该矢量的元素,则可能会得到该异常 – cmbaxter
如果'i'大于矢量的当前元素数,'vector.get(i)'将抛出异常。 – NINCOMPOOP