[英]Sequentially processing file in threadpool executor
我們使用JDK 7 watchservice來查看可以包含xml或csv文件的目錄。 這些文件放在線程池中,稍后處理並推送到數據庫中。此應用程序運行以便永遠觀察目錄並在可用時保持處理文件。 XML文件很小並且不需要時間,但是每個csv文件可以包含超過8萬條記錄,因此處理需要時間來放入數據庫。 當從線程池中處理15個csv文件時,Java應用程序會給我們帶來內存錯誤。 有什么方法當csv文件進入線程池時,它可以被串行處理,即一次只有一個。
當從線程池中處理15個csv文件時,Java應用程序會給我們帶來內存錯誤。 有什么方法當csv文件進入線程池時,它可以被串行處理,即一次只有一個。
如果我理解,如果超過某個閾值,您希望停止添加到池中。 有一種簡單的方法可以使用阻塞隊列和被拒絕的執行處理程序。
請參閱以下答案:
總結一下,您可以執行以下操作:
// only allow 100 jobs to queue
final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(100);
ThreadPoolExecutor threadPool =
new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, queue);
// we need our RejectedExecutionHandler to block if the queue is full
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
// this will block the producer until there's room in the queue
executor.getQueue().put(r);
} catch (InterruptedException e) {
throw new RejectedExecutionException(
"Unexpected InterruptedException", e);
}
}
});
這意味着它將阻止添加到隊列中,不應耗盡內存。
我會采取不同的方法來解決你的問題,我猜你有一切正常,除非你開始在內存中讀取太多數據。
不確定你是如何讀取csv文件的,建議使用LineReader並讀取例如500行處理它們然后讀取接下來的500行,所有大文件都應該以這種方式處理,因為無論你增加多少內存參數,一旦你有一個更大的文件要處理,你就會內存不足,所以使用一個可以批量處理記錄的實現。 這需要一些額外的編碼工作,但無論你需要處理多大的文件,都不會失敗。
干杯!!
你可以試試:
-Xmx
JVM選項增加JVM的內存 使用其他執行程序一次減少已處理文件的數量。 一個徹底的解決方案是使用SingleThreadExecutor
:
public class FileProcessor implements Runnable { public FileProcessor(String name) { } public void run() { // process file } } // ... ExecutorService executor = Executors.newSingleThreadExecutor(); // ... public void onNewFile(String fileName) { executor.submit(new FileProcessor(fileName)); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.