【发布时间】:2014-12-11 20:12:48
【问题描述】:
我在通过 ForkJoinPool 加载大量图像时遇到问题,我正在使用超线程的 4 核 Intel 进行测试,因此有 8 个逻辑线程。但是,我将池限制为只有 4 个线程。我收到来自 ImageIO 的错误,无法找到图像。
public class LoadImages extends RecursiveAction {
private static final long serialVersionUID = 1L;
//this is an example
private static int threadThreshold = totalImages/totalThreads + 2;
private String[] imgArr;
private int arrStart = 0;
private int arrSize = 0;
public LoadImages(String[] imgs, int start, int size) {
imgArr = imgs;
arrSize = size;
arrStart = start;
}
protected void processImages(){
BufferedImage img = null;
for (int i = arrStart; i < arrStart + arrSize; i++) {
try{
img = ImageIO.read(new File(imgArr[i]));
} catch (IOException | CMMException | NullPointerException e) {
System.out.println(imgArr[i]);
e.printStackTrace();
img = null;
}
...
}
}
protected void compute() {
// Check the number of files
if (arrSize <= threadThreshold) {
processImages();
return;
} else {
int split = arrSize / 2;
invokeAll(new LoadImages(imgArr, arrStart, split), new LoadImages(imgArr, arrStart + split, arrSize - split));
}
}
}
任何关于我做错了什么的见解都会很棒,我注意到只有当我有超过 1700 张图片并且所有图片都超过 5MB 时它才会中断。
这是我从 Java 收到的错误:
javax.imageio.IIOException: Can't create an ImageInputStream!
at javax.imageio.ImageIO.read(Unknown Source)
当我知道文件在那里时。 我将此代码用作指南: https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
【问题讨论】:
-
您的第一个错误是在compute() 和invokeall() 中。您应该对第一个 LoadImages 使用 fork(),对第二个 LoadImages 使用 compute()。查看 ForkJoinPool 的 JavaDoc。 invokeAll() 在继续之前等待所有调用的任务完成。
-
@edharned 我明白你的意思,我试过了,实际上是从那里开始的。但是,如果我这样做 loadImg1.fork(); loadImg2.compute(); loadImg1.join();它做同样的事情我错了吗?看看我遵循的示例:docs.oracle.com/javase/tutorial/essential/concurrency/… 无论哪种方式,我仍然会遇到相同的错误。
-
为了更快的速度,尝试设置
ImageIO.useCache(false)。另外,我认为您应该使用 cmets 中提到的IOException将问题更新为以下答案之一。这很可能是原因。也许您的进程可以拥有的打开文件数量或类似文件数量受到限制? -
我将 IOException 添加到 titlevand 我还将尝试将 useCache 设置为 false,看看是否有帮助。
-
我仍然认为使用带有线程池的队列会更容易(生产者/消费者)。使用 FJ 进行异步处理有局限性。你可以只计算你需要的任务数量,然后 fork() 那么多,因为你不等待完成。您遇到的错误可能是@Wes Cumberland 在下面所说的。看来您正在将并发性与并行性混为一谈。
标签: java multithreading javax.imageio forkjoinpool work-stealing