如何在这种情况下清除我的ArrayList大小为100:

时间:2017-05-30 15:10:12

标签: java concurrentmodification

我的最终目标是在Executor服务中实现行的批处理。我有以下代码片段:

while ((bLine = bufferedReader.readLine()) != null) {
    // We will use an array to hold 100 lines, so that we can batch process in a
    // single thread
    batchArray.add(bLine);
    switch (batchArray.size()) {
        case 100:
            Future<?> future = executor.submit(new LocalThreadPoolExecutor(batchArray, closeableHttpClient, httpPost));
            futures.add(future);
           // batchArray.clear() <--- point of failure
            break;
        default:
            logger.info("Batch size in switch: "+batchArray.size());

    }
}

现在,如果我在batchArray.clear()中执行case 100,我会收到concurrentModificationException。无法确定如何从文件中读取数组列表并将100行发送到执行程序。

下面的

是堆栈跟踪:

java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at consumer.ril.com.LocalThreadPoolExecutor.run(LocalThreadPoolExecutor.java:37)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

当我尝试读取在此类的构造函数中传递的batchArray时,我在LocalThreadPoolExecutor类中得到了异常。

3 个答案:

答案 0 :(得分:1)

您的对象let centeredParagraphStyle = NSMutableParagraphStyle() centeredParagraphStyle.alignment = .center let attributes: [String : Any] = [NSParagraphStyleAttributeName: centeredParagraphStyle] 通过引用传递,有关详细信息,请参阅此处: Is Java "pass-by-reference" or "pass-by-value"?

因此,您的班级batchArray仍然有对它的引用,无法修改。

使用LocalThreadPoolExecutor或使参数clone起作用。

答案 1 :(得分:1)

简单的解决方案 - 您需要传递给LocalThreadPoolExecutor数组副本并清理原始数组。

Future<?> future = executor.submit(new LocalThreadPoolExecutor(new ArrayList<>
(batchArray), closeableHttpClient, httpPost));
futures.add(future);
batchArray.clear();

答案 2 :(得分:1)

有些代码在LocalThreadPoolExecutor中使用list(Iterator)。在某些时候,它意识到列表已被修改(清除)。您应该使用该列表的另一个副本。

由于您不需要主线程中的项目,您可以为每个批次显式创建新列表并将其传递给处理器:

类似的东西:

{   
...
     while ((batch = getNextBatch(bufferedReader, 100)).size() > 0) {
        futures.add(
            executor.submit(new LocalThreadPoolExecutor(batch, closeableHttpClient, httpPost))
        );
    }
...
}

获得下一批:

List<String> getNextBatch(BufferedReader bReader, int batchSize) throws IOException {
    List<String> batch = new ArrayList<>(batchSize);
    while (batch.size() < batchSize && (bLine = bReader.readLine()) != null) {
        batch.add(bLine);
    }
    return batch;
}