我目前正在使用 ExecutorService 在 CopyOnWrite ArrayLists 中发送批量字符串以并行处理,其中处理这些列表的 Runnable 任务需要遍历列表并对每个字符串进行处理。
在遇到常规 ArrayLists 的并发问题后,我尝试使用 CopyOnWriteArrayLists,因为它们是线程安全的,但是我的结果现在不一致。也就是说,我每次运行程序都会得到不同的结果,这表明在每个 Runnable 任务可以完全迭代它之前,arraylist 的内容会以某种方式发生变化。
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
}
}
可运行任务不对数组列表进行任何修改,它只遍历列表并使用列表的字符串元素进行处理。
CopyOnWriteArrayList 更改的唯一位置是在每个新的 Runnable 任务的实例化处。
当我传入单个字符串而不是批处理时,我得到了一致且正确的结果,但是当我开始在 String ArrayLists 中使用批处理时,我得到了不一致的结果,这表明有些东西正在损害 CopyOnWriteArrayList 批处理的并发性,尽管它被认为是线程-安全的。
任何帮助表示赞赏,谢谢!
编辑:这是我的批次正在构建的地方:
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);