Разве это возможно? Объясните пожалуйста, когда такое возможно и почему?
Даже не знаю, как показать какой-либо кусок кода. Во-первых, ситуация очень странная. Во-вторых, к ней меня привела длинная цепочка вызовов (классы сильно взаимосвязаны). Даже не могу предположить где может быть проблема. Скажу только, что я получаю исключение запуская сложную задачу в SwingWorker.
UPD: Благодаря полученным ответам, я понял на какой метод следует обратить наиболее пристальное внимание:
@Override
protected Void doInBackground() throws Exception {
solver = new MultidimensionalSolver(manager.getTask());
manager.getTask().setSolution(solver.getSolution().getSolution());
while (!solver.isSolutionFind() && flag) {
solver.findSolution();
manager.getTask().setSolution(
solver.getSolution().getSolution());
publish();
iter++;
}
return null;
}
Здесь класс MultidimensionalSolver работает с теми же данными, которые выводятся на экран в методе process(), вызываемом при вызове publish(). Получается поток в методе publish настолько обгоняет поток в методе doInBackground?
Ответ
Такое может запросто случиться, если доступ к вашему ArrayList идет из нескольких потоков, при этом отсутствует синхронизация. Судя по тому, что вы используете SwingWorker, именно это и происходит. Сценарий может быть такой:
Первый поток пытается взять элемент с индексом 2. При этом в
коллекции, допустим, всего 1 элемент.
В методе rangeCheck код этого потока заходит внутрь условия:
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
Второй поток добавляет 2 элемента (теперь их становится 3).
Первый поток выбрасывает исключение со странным сообщением,
поскольку метод outOfBoundsMsg подхватил новое значение size
Решение: синхронизировать доступ (и чтение, и запись) к коллекции с помощью локов, либо использовать потокобезопасный вариант коллекции.
Комментариев нет:
Отправить комментарий