2011-03-09 76 views
4

我有一个动态保存大量文件的目录。目前有一项任务会不时列出文件并按顺序处理它们(写入数据库)。由于文件数量的增加,有必要对这些文件进行并行处理。你能给我一些想法和java代码示例吗?并发文件处理

回答

0

这不是如果你熟悉Java并发真的很明显,所以我会采取一看的Java Concurrency Tutorial开始。这是一个开始的好地方。

然后请记住,任何需要被多个线程访问的对象都应该是不可变的或同步的。

之后,您可以使用ExecutorService拥有一个线程池,并且有多个线程可以同时运行。

我知道,这是不一样的过程实质上但假设你知道如何处理这些文件,你可以在下面的问题就来看看关于在不同的上下文中多线程: questions around synchronization in java; when/how/to what extent

Parallel-processing in Java; advice needed i.e. on Runnanble/Callable interfaces

3

使用一个ExecutorService。创建Executors.newFixedThreadExecutor(n);你也许可以使文件处理成一个单一的可运行(或可调用)任务,并将它传递的,你可以在

ExecutorService service = Executors.newFixedThreadExecutor(10); 

for(final File file : directory.listFiles()){ 
    service.submit(new Runnable(){ 
     public void run(){ 
      //do work here on file object 
     } 
    }); 
} 
1

工作文件看一看的java.nio中的监视在役API 。文件。以下是文档和教程:http://download.oracle.com/javase/tutorial/essential/io/notification.html

此服务允许您在目录上注册文件通知更改。对于每一个通知,你可以做任何你想要的处理。可能比实现你自己的事容易得多。

+0

+1:虽然这不能回答这个问题,但对于海报来说这是一个很好的建议。 – Karmastan 2011-03-09 15:42:47

0

如果我正确理解你的单个任务处理从读取到数据库加载。您可以根据性质(以数据库为中心,以CPU为中心或以IO为中心)将此任务分解为不同的任务。例如,您可以执行以下不同的任务:

  1. 当前任务,从目录中选取文件并将其传递给下一个任务。

  2. IO Centric - 新任务读取文件并存储在内存中,然后传递给下一个taks。

  3. 以数据库为中心 - 新任务将数据从内存加载到数据库,然后清理内存。

  4. 以IO为中心 - 将文件移动到其他地方。

要进一步提高性能,可以使用线程池实现任务2,3,4。这将允许并行处理多个文件。根据任务的复杂性,您可以添加或删除列表中的任何任务以满足您的要求。

+0

除了第2步以外,还有相当不错的建议。将整个文件读入内存几乎是一个不错的主意。将步骤2/3合并为“从文件到数据流的流数据”。 – jtahlborn 2011-03-09 16:38:24

+0

我同意内存部分,但是要记住文件的位置。如果文件位于远程位置,则可以创建本地副本或将其保存在内存中(如果确定文件大小不会造成任何伤害)。此外,应用程序还可以有一些逻辑来限制内存使用。 – Amit 2011-03-09 16:42:33