如何处理具有多个线程的文件,以便每个文件仅由一个线程处理

时间:2010-08-27 13:31:08

标签: java multithreading

我目前有一个产生50个线程的Java程序,其目标是查看一个目录,该目录中有许多文件被写入并将这些文件上传到ftp服务器然后删除它们。现在,我有一种超级hacky方式在每个线程中循环遍历dir并在ConcurrentMap上设置锁定以跟踪线程何时处理相同的图像以防止重复工作。它工作但似乎不对。

所以问题是..在Java中,什么是在多线程程序中观察目录并确保每个线程仅在没有其他人拥有的文件上运行的首选方式。

更新:我正在考虑创建一个线程池,每个线程的警告都有一个ftpclient连接,我必须保持打开并防止超时。

更新:如何使用http://download.oracle.com/javase/tutorial/essential/io/notification.html

5 个答案:

答案 0 :(得分:4)

使用ExecutorService将工作提交与线程逻辑本身的线程分离(另请查看父接口Executor的文档以了解更多有关其用途的信息)

使用ExecutorService,您只需将工作(在您的情况下为文件)提供给它,线程将在可用时获取工作。您可以配置许多ExecutorServices的选项和风格:单线程,最大线程数,无界线程池等。

答案 1 :(得分:1)

也许有一个主线程搜索目录并将任务交给工作线程?

答案 2 :(得分:1)

国际海事组织,它试图写一些自己这样做的东西是很麻烦的。并行批处理有很多细微差别,最好将API学习到为您完成的框架。

过去我曾使用Spring Batch(开源)和Flux(需要许可证)。它们都允许您配置监视文件目录的作业,然后以并行方式处理这些文件。只要您愿意花时间学习他们的API,那么您就不必担心同步哪个进程处理哪些文件。

快速说明Spring BatchFlux的优缺点:

  • Spring批处理主要是XML配置,而Flux有一个很好的GUI设计器
  • 如果您已经熟悉Spring框架,那么批处理将更加自然。 (否则,作为起点,他们的文档非常适合基本用例)
  • Spring批处理需要从外部进行调度(通常使用Quartz),而Flux也包括调度
  • 对于像监控目录/ FTP / SFTP /电子邮件以开始工作这样的事情,Flux更好(并且更直观)

我确信还有其他框架可以做到这一点......这些只是我熟悉的两个。

答案 3 :(得分:0)

我会设置一个文件处理程序类,它接受一个目录并具有一个并发锁定的.nextFile函数,该函数传递目录中的下一个文件。这样每个线程都会请求一个文件,每个线程都会获得一个唯一的文件

答案 4 :(得分:0)

解决方案真的需要多线程吗?除非每个连接限制到目标FTP服务器的最大上传速度,否则一次发送一个更容易吗?

通过单个FTP连接以1Mbps(假设最大上传速度)顺序发送50个1MB的文件,并不比使用50个FTP连接以~20Kbps同时发送相同的50个文件慢,不是吗?