2013-05-29 7 views
-1

Я пытаюсь настроить мои концепции на ядро ​​Java и многопоточность. При чтении какой-то книги я нашел нижеприведенный код может бросить ArrayIndexOutOfBoundsException, если к вектору обращается какой-то другой поток.Исключение в доступе к вектору при доступе к элементам

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

Я действительно много пробовал, но не смог выяснить, как? Может ли кто-нибудь помочь мне в этом.

+2

Из этого кода один, невозможно сказать. Что делает «doSomething»? Существуют ли какие-либо другие потоки, которые могут обращаться к «вектору» параллельно? –

+3

Если другой поток удаляет элемент вектора во время его обработки, вы можете получить это исключение – cmbaxter

+0

'vector.get (i)' будет генерировать исключение, если 'i' больше, чем текущий счетчик элемента вектора. – NINCOMPOOP

ответ

1

В Vector есть все поля, синхронизированные. В этом случае мы выполняем такие операции, как получение размера вертера, и мы пытаемся получить доступ к элементу 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). Самый простой способ исправить это состоит в том, чтобы покрыть тело метода iterate() блоком synchronized (vector) {...} или использовать более сложный подход.

+0

спасибо большое. У меня есть причина. как я упомянул в вопросительном комментарии, я думал, что только код может привести к исключению. – daksh

Смежные вопросы