【发布时间】:2020-04-20 01:09:12
【问题描述】:
编辑:谢谢马克,对于那些有类似问题的人,我的问题是我先创建了一个可运行类的 Thread 实例,然后将线程提交给 executorservice。
它帮助我弄清楚,实际上,当我使用 ExecutorService 时,是否有未捕获的异常;它不会通知您,它将取消该过程,没有通知。这就是我处理不完整的原因。
我有一个对象的 ArrayList,我想批量处理多线程,但限制在给定时间运行的线程数。我发现 ExecutorService 可以处理这个问题。但是在测试它是否正在处理每条记录时,它似乎只处理了我传递给它的对象的一小部分。
编辑:我已经删除了它的多线程部分,并在不使用执行器服务的情况下像平常一样处理小批量(仅 710)的对象,它工作正常;线程是否有可能完成得太快并且处理不正确?这意味着通常一次处理大约 300k-800k 条记录;这就是为什么我想多线程。
public void processContainerRecords(ArrayList<? extends ContainerRecord> records) {
int cores = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(cores);
int batchSize = Settings.LOGIC_BATCH_SIZE;//100
int batches = (int) Math.ceil((double) records.size() / (double) batchSize);
ArrayList<Future<?>> threads = new ArrayList<Future<?>>();
LogicProcessor newHandler = null;
for (int startIndex = 0; startIndex < records.size(); startIndex += batchSize + 1) {
if (records.size() < batchSize) {
newHandler = new LogicProcessor(mainGUI, records.subList(startIndex, records.size()));
} else {
int bound = (startIndex + batchSize);
if (bound > records.size()) {
bound = records.size();
}
newHandler = new LogicProcessor(mainGUI, records.subList(startIndex, bound));
}
Thread newThread = new Thread(newHandler);
Future<?> f = executor.submit(newThread);
threads.add(f);
}
executor.shutdown();
int completedThreads = 0;
while (!executor.isTerminated()) {//monitors threads and waits until completion
completedThreads = 0;
for (Future<?> f : threads) {
if (f.isDone()) {
completedThreads++;
}
}
//currentProgress = completedThreads;
}
for (ContainerRecord record : records) {//checks if each record has been processed
System.out.println(record.getContainer() + ":" + record.isTouched());
}
}
这是启动线程实例的 LogicProcessor 类
private List<? extends ContainerRecord> archive;
private GUI mainGUI;
public LogicProcessor(GUI mainGUI, List<? extends ContainerRecord> records) {
this.mainGUI = mainGUI;
this.archive = records;
}
@Override
public void run() {
handleLogic();
}
private void handleLogic() {
Iterator iterator = archive.iterator();
while (iterator.hasNext()) {
ContainerRecord record = (ContainerRecord) iterator.next();
record.touch();//sets a boolean in the object to validate if it has been processed yet.
}
}
输出:在处理的 710 条记录(对象)中,691 条从未被处理/触摸过,只有 19 条已经处理。
这有什么问题?我已经尝试了很多方法,甚至制作了一个类 LogicProcessor 的数组并将实例保存在数组中以避免任何类型的 GC 删除实例。我不确定它为什么不处理这些记录。
【问题讨论】:
标签: java arraylist batch-processing executorservice