2013-05-29 51 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