Java:创建大量可调用项或将迭代器结果分发给线程?

Java:创建大量可调用项或将迭代器结果分发给线程?,java,parallel-processing,Java,Parallel Processing,我已经编写了一个应用程序来处理图像。我的操作代码应应用于文件夹中的所有图像(每个文件夹最多100万个) 到目前为止,我为文件夹中的每个图像创建了一个可调用的(这是一个处理图像的工作人员),并将其添加到数组列表。然后我使用FixedThreadPool的invokeAll方法来并行化工作 然而,我的问题是:这个设计好吗?我怀疑首先向数组列表中添加100万个元素是否真的有意义。我在考虑向所有线程传递一个迭代器(在文件上),让每个线程获取下一个元素并进行处理(不幸的是,存在阻塞问题),但这有意义吗?我

我已经编写了一个应用程序来处理图像。我的操作代码应应用于文件夹中的所有图像(每个文件夹最多100万个)

到目前为止,我为文件夹中的每个图像创建了一个
可调用的
(这是一个处理图像的工作人员),并将其添加到
数组列表
。然后我使用
FixedThreadPool
invokeAll
方法来并行化工作


然而,我的问题是:这个设计好吗?我怀疑首先向数组列表中添加100万个元素是否真的有意义。我在考虑向所有线程传递一个
迭代器
(在文件上),让每个线程获取下一个元素并进行处理(不幸的是,存在阻塞问题),但这有意义吗?

我听起来还可以,即使它不一定非常有效,而且扩展性也不太好。另一种设计可以是:

  • 创建一个
    ArrayBlockingQueue
    大小大于FixedThreadPool(比如两倍大)
  • 创建一个
    FileVisitor
    ,我们称之为
    ImageFileVisitor
    ,它在
    visitFile
    方法
    中将访问的文件放入队列-这是一个阻塞调用,因此它将等待队列未满
  • 根据您的池大小创建尽可能多的
    可调用的
    s,并让每个
    从队列中取出
    ,然后做他们必须做的事情

注意:线程池的大小应该相当小。如果您的图像处理非常繁重,请使用处理器的数量来确定大小,如果处理器的数量比较小,并且大部分时间都花在读取/写入文件上,请使用较小的大小。

FixedThreadPool
使用
LinkedBlockingQueue
of
Integer.MAX\u VALUE

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

使用上述方法,您的
put
调用将阻塞
Q
中的
1000
可运行项,但一旦其中一些完成,
put
将继续。通过执行
invokeAll
,将有10个运行线程和最多1000个可运行实例。

您有一百万个CPU吗?对不起,我不在谷歌工作;-)我也是。我的意图是暗示“常识”,你通常不想创建比你有CPU更多的线程。是的,明白了。但是我并没有创建比CPU更多的线程。对不起,我没有明确说明。我只创建了一百万个可调用对象,但是线程的数量大约是5个。听起来很不错!我会试着实施它,并很快回复你!谢谢@navige关于FileVisitor,最简单的方法是扩展SimpleFileVisitor并重写
visitFile
(并在重写的方法末尾调用
super.visitFile()
):-)是!这也是我刚刚意识到的!
int nThreads = 10;
int maxQSize = 1000;
ExecutorService service = new ThreadPoolExecutor(nThreads, nThreads,
                                          0L, TimeUnit.MILLISECONDS,
                                          new LinkedBlockingQueue<Runnable>(maxQSize))