Выполняет многопоточную загрузку тысяч изображений, вызывая IOException

У меня проблема с загрузкой большого количества изображений через 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 изображений и все изображения имеют размер 5 МБ и более.

Вот ошибка, которую я получаю от 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 ответа

Мне кажется, ошибка ImageIO, когда внутренне создает ImageInputStream. Вы пытались читать изображения с помощью ImageInputStream? Подобно:

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

Кажется случайным. Я думаю, это может быть просто ошибка оборудования или ОС. Предполагая, что это проблема масштабирования, я советую с вашими 1700+ изображениями, что вам, вероятно, будет лучше настроить это где-нибудь в облаке - это может сэкономить много времени и головных болей

Если вы идете, проверьте источник ImageIO.read(File) а также ImageIO.read(ImageInputStream) Вы можете видеть, что видеть, что ImageIO повторно использует случаи ImageReaderи эта статья говорит, что ImageReader не является потокобезопасным. Вам, вероятно, придется создать свой собственный ImageReaders для использования в отдельных темах.

Также вы должны оценить, насколько эта стратегия многопоточности-ввода-вывода действительно приносит вам пользу. Если вы пытаетесь получить данные изображений с вращающегося жесткого диска, ваш процесс, вероятно, будет связан с вводом / выводом, и распараллеливание загрузки не даст вам много.

Другие вопросы по тегам