В настоящее время я отправляю партии строк в CopyOnWrite ArrayLists с ExecutorService для обработки параллельно, где задача Runnable, обрабатывающая эти списки, должна перебирать список и обрабатывать каждую строку.Неверная итерация CopyOnWriteArrayList с многопоточным?
После того, как вы столкнулись с проблемами с параллелизмом с регулярными массивами ArrayLists, я попытался использовать CopyOnWriteArrayLists, потому что они потокобезопасны, однако мои результаты теперь несовместимы. То есть, я получаю разные результаты при каждом запуске программы, предполагая, что содержимое arraylist каким-то образом изменено, прежде чем каждый Runnable taks сможет полностью перебрать его.
public static class BatchRunnable implements Runnable {
private CopyOnWriteArrayList<String> batch;
BatchRunnable(CopyOnWriteArrayList<String> batch){
this.batch = batch;
}
@Override
public void run(){
//iterate over batch and work with String elements
//make no modifications to batch
}
}
с выполняемой задачей не делают никаких изменений в ArrayList, это только итерация по списку и использует строковые элементы списка, чтобы сделать обработку.
ТОЛЬКО место, в которое изменяется экземпляр CopyOnWriteArrayList, находится в его экземпляре с каждой новой задачей Runnable.
Когда я проходил в одиночных строках вместо пакетирования, я имел последовательные и правильные результаты, но когда я начал использовать партию в Струнных ArrayLists, я получил противоречивые результаты, предлагая что-то компрометирует параллелизм CopyOnWriteArrayList партии , несмотря на то, что он якобы является потокобезопасным.
Любая помощь приветствуется, спасибо!
EDIT: Вот где мои партии строятся:
Runnable worker = null;
while((line = br.readLine()) != null) {
recordBatch.add(line);
if(recordBatch.size() == 100){
worker = new BatchRunnable(recordBatch);
executor.execute(worker);
recordBatch.clear();
}
}
executor.shutdown();
executor.awaitTermination(60,TimeUnit.SECONDS);
Если вы были полностью построения партии, прежде чем итерацию над ними (то есть никакие другие потоки не изменяли вещи), то я бы ожидал, что вы будет хорошо с ArrayList в любом случае. Это говорит о том, что у вас есть что-то неожиданное изменение ваших партий. Вы должны изучить эту сторону вещей. –
Я добавил, как я строю партии, может быть, есть основания полагать, что это вызывает проблемы? – ddnm
Боковой комментарий: вместо этого вы должны использовать блокирующую очередь - это именно то, что они должны были делать ... – assylias