В 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) {...}
или использовать более сложный подход.
Из этого кода один, невозможно сказать. Что делает «doSomething»? Существуют ли какие-либо другие потоки, которые могут обращаться к «вектору» параллельно? –
Если другой поток удаляет элемент вектора во время его обработки, вы можете получить это исключение – cmbaxter
'vector.get (i)' будет генерировать исключение, если 'i' больше, чем текущий счетчик элемента вектора. – NINCOMPOOP