【发布时间】:2021-03-25 05:39:54
【问题描述】:
我正在使用 java 执行器服务将数据从一个数据库传输到另一个数据库。
ExecutorService executor = (ExecutorService) Executors.newFixedThreadPool(10);
一旦执行器服务被初始化。以 500 条为一组从源数据库中检索记录,并将这些记录索引到目标数据库中。
while(true){
List<?> docs = getDataFromSourceDB();
if(docs.size > 0){
IndexdataToTargetDBThread thread = new IndexdataToTargetDBThread(docs)
executor.submit(thread);
}else{
break;
}
}
executor.shutdown()
while (!eService.isTerminated()) {
}
函数getDataFromSourceDB() 在每次调用时返回 500 条记录,如果没有可用记录,它将返回一个空数组。 IndexdataToTargetDBThread 类实现了 Runnable。它将给定文档索引到目标数据库。
上述函数运行时出现Out Of Memory异常。 Source DB 有接近 1M 的记录,因此 while 循环被处理了大约 2000 次。处理大约 700 次后,出现内存不足,整个 DB 传输过程失败。有没有有效的方法来处理这个问题?
【问题讨论】:
-
也许不要同时保留这么多未完成的工作。跟踪未完成的工作数量,如果超过 100 个,请在排队之前等待。在之前的工作完成之前,它们不会被执行。
-
您没有使用执行程序来限制负载。您在提交到线程池时获取所有数据。您应该在 Runnable 的
run()方法中调用getDataFromSourceDB(),以便在任何给定时间最多加载 (500*10) 条记录。 -
可以给我
IndexdataToTargetDBThread课的内容吗?也许你没有打电话给EntityManager.clear() -
@dungtavan :这有一些我无法掩盖和分享的机密信息。但是,写入目标数据库处理得很好。不使用 EntityManager.clear()。数据库连接已正确打开、处理和关闭。就像 ernest 提到的那样,我试图限制流入数据。
-
顺便说一句……用
executor.awaitTermination()替换那个紧密的循环while (!eService.isTerminated()) {}。
标签: java multithreading executorservice