问题多线程加载导致IOException的数千个图像的加载

时间:2014-12-11 20:12:49

标签: java multithreading javax.imageio forkjoinpool work-stealing

我在通过ForkJoinPool加载大量图像时出现问题,我正在测试具有超级主题的4核Intel,因此有8个逻辑线程。但是,我将Pool限制为仅4个Threads。我收到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

3 个答案:

答案 0 :(得分:0)

似乎有点随机。我的猜测是它可能只是硬件或操作系统错误。假设这是一个扩展问题,我对你的1700+图像的建议是,你可能最好不要在某个地方设置这个 - 可以节省大量的时间和头痛

答案 1 :(得分:0)

在我内部创建ImageInputStream时,在我看来是一个ImageIO错误。您是否尝试使用ImageInputStream读取图像?像:

InputStream is = new FileInputStream("path");
ImageInputStream iis = ImageIO.createImageInputStream(is);
BufferedImage bufImage = ImageIO.read(iis);

答案 2 :(得分:-1)

如果你去检查ImageIO.read(File)ImageIO.read(ImageInputStream)的来源,你可以看到ImageIO重新使用ImageReader的实例,而this article说{ {1}}不是线程安全的。您可能必须创建自己的ImageReader以在单独的线程中使用。

此外,您应该测量这种多线程IO策略真正让您获益的程度。如果您正试图从旋转的硬盘驱动器中取出图像数据,那么您的进程可能会受到I / O限制,并且并行化加载将不会给您带来太多帮助。