簡體   English   中英

在線程池執行器中順序處理文件

[英]Sequentially processing file in threadpool executor

我們使用JDK 7 watchservice來查看可以包含xml或csv文件的目錄。 這些文件放在線程池中,稍后處理並推送到數據庫中。此應用程序運行以便永遠觀察目錄並在可用時保持處理文件。 XML文件很小並且不需要時間,但是每個csv文件可以包含超過8萬條記錄,因此處理需要時間來放入數據庫。 當從線程池中處理15個csv文件時,Java應用程序會給我們帶來內存錯誤。 有什么方法當csv文件進入線程池時,它可以被串行處理,即一次只有一個。

當從線程池中處理15個csv文件時,Java應用程序會給我們帶來內存錯誤。 有什么方法當csv文件進入線程池時,它可以被串行處理,即一次只有一個。

如果我理解,如果超過某個閾值,您希望停止添加到池中。 有一種簡單的方法可以使用阻塞隊列和被拒絕的執行處理程序。

請參閱以下答案:

在Java中處理HTTP調用的大文件

總結一下,您可以執行以下操作:

// 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行,所有大文件都應該以這種方式處理,因為無論你增加多少內存參數,一旦你有一個更大的文件要處理,你就會內存不足,所以使用一個可以批量處理記錄的實現。 這需要一些額外的編碼工作,但無論你需要處理多大的文件,都不會失敗。

干杯!!

你可以試試:

  1. 使用-Xmx JVM選項增加JVM的內存
  2. 使用其他執行程序一次減少已處理文件的數量。 一個徹底的解決方案是使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM