在线程池执行器中顺序处理文件

时间:2013-09-05 17:23:42

标签: java multithreading concurrency threadpool watchservice

我们使用JDK 7 watchservice来查看可以包含xml或csv文件的目录。这些文件放在线程池中,稍后处理并推送到数据库中。此应用程序运行以便永远观察目录并在可用时保持处理文件。 XML文件很小并且不需要时间,但是每个csv文件可以包含超过8万条记录,因此处理需要时间来放入数据库。当从线程池中处理15个csv文件时,Java应用程序会给我们带来内存错误。有什么方法当csv文件进入线程池时,它可以被串行处理,即一次只有一个。

3 个答案:

答案 0 :(得分:1)

  

当从threadpool处理15个csv文件时,Java应用程序会给出我们的内存错误。当csv文件进入线程池时,有什么方法可以串行处理,即一次只能处理一个。

如果我理解,如果超过某个阈值,您想要停止添加到池中。有一种简单的方法可以使用阻塞队列和被拒绝的执行处理程序。

请参阅以下答案:

  

Process Large File for HTTP Calls in Java

总结一下,您可以执行以下操作:

// 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);
           }
    }
});

这意味着它将阻止添加到队列中,不应耗尽内存。

答案 1 :(得分:1)

我会采取不同的方法来解决你的问题,我猜你有一切正常,除非你开始在内存中读取太多数据。

不确定您是如何阅读csv文件的,建议使用LineReader并阅读例如500行处理它们然后读取接下来的500行,所有大文件都应该以这种方式处理,因为无论你增加多少内存参数,只要你有更大的文件需要处理,你就会内存不足,所以使用一个可以批量处理记录的实现。这需要一些额外的编码工作,但无论你需要处理多大的文件都不会失败。

干杯!!

答案 2 :(得分:0)

您可以尝试:

  1. 使用-Xmx JVM选项
  2. 增加JVM的内存
  3. 使用其他执行程序一次减少已处理文件的数量。一个彻底的解决方案是使用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));
    }