我的最终目标是在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
类中得到了异常。
答案 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;
}