gpt4 book ai didi

java - CopyOnWriteArrayList 迭代器与多线程不一致?

转载 作者:行者123 更新时间:2023-12-03 12:56:07 24 4
gpt4 key购买 nike

我目前正在使用 ExecutorService 在 CopyOnWrite ArrayLists 中发送批处理字符串以进行并行处理,其中处理这些列表的 Runnable 任务需要遍历列表并对每个字符串进行处理。

在遇到常规 ArrayList 的并发问题后,我尝试使用 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
}
}
  • runnable 任务不会对数组列表进行任何修改,它只遍历列表并使用列表的字符串元素进行处理。
  • 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);

    最佳答案

    查看您的 while循环:

    while((line = br.readLine()) != null) {
    recordBatch.add(line);
    if(recordBatch.size() == 100){
    worker = new BatchRunnable(recordBatch);
    executor.execute(worker);
    recordBatch.clear();
    }

    }

    您正在将引用传递给相同的 list在所有 BatchRunnable .所以,一旦你改变了 list在一处,它将反射(reflect)在所有引用中。因此,一旦您使用 recordBatch.clear() 清除列表,所有引用的列表都是空的,即使是您在 BatchRunnable 中的引用。 .这就是为什么你得到不一致的结果。

    你应该通过一个 copy您的 recordBatch在您的 BatchRunnable 中列出:
    worker = new BatchRunnable(new ArrayList<String>(recordBatch));

    关于java - CopyOnWriteArrayList 迭代器与多线程不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17803515/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com