2013-05-29 48 views
-1

我正在尝试调用我关于核心Java和多线程的概念。当读一些书时,我发现 下面的代码可能会抛出ArrayIndexOutOfBoundsException如果矢量以某种方式被另一个线程访问。在访问元素时访问向量中的异常

for (int i = 0; i < vector.size(); i++){ 
    doSomething(vector.get(i)); 
} 

我真的尝试了很多,但无法弄清楚如何? 任何人都可以帮助我。

+2

仅凭这个代码,就不可能说。 “doSomething”做什么?有没有其他线程可以并行访问'vector'? –

+3

如果另一个线程在处理它时删除了该矢量的元素,则可能会得到该异常 – cmbaxter

+0

如果'i'大于矢量的当前元素数,'vector.get(i)'将抛出异常。 – NINCOMPOOP

回答

1

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()方法体或使用更复杂的方法。

+0

非常感谢。 我明白了。正如我在问题评论中提到的那样,我一直认为代码本身可能导致异常。 – daksh