ImageIO синхронизирован

У меня есть веб-приложение, в котором пользователи загружают изображения. Мы проверяем данные изображения с помощью ImageIO.read() и выполняем несколько простых преобразований полученного BufferedImage перед его сохранением на диск.

Выполняя нагрузочное тестирование, мы поняли, что когда одновременно поступает много запросов, они блокируются в вызове ImageIO.read(). Копнув глубже, мы заметили, что JPEGImageReader синхронизирован и одновременно создается только одно BufferedImage.

Кто-нибудь еще сталкивался с этим? Я гуглил это в течение нескольких дней и не встречал другого человека, у которого была эта проблема, так что, возможно, я делаю что-то не так. Я не могу придумать никакой логической причины, почему это могло бы быть. Кажется, это связано с невозможностью создания отдельных модулей чтения и записи для каждого образа из-за какой-то проблемы с утечкой памяти, но это объяснение кажется мне довольно тонким.

РЕДАКТИРОВАТЬ: Вот инструмент производительности, который разбивает то, что занимает так много времени. Я считаю, что это связано с тем, что все потоки ожидают блокировки синхронизации, JPEGImageReader источник.

РЕДАКТИРОВАТЬ: Библиотеки JAI работали бы, за исключением того, что OpenJDK удалил поддержку его критических частей, явно кодека JPEG.

РЕШЕНИЕ. Учитывая количество времени, которое я потратил, пытаясь найти альтернативное решение и не найдя его, моим лучшим решением была асинхронная обработка изображений по отношению к запросам. Итак, когда приходит запрос, необработанные данные изображения сохраняются как предположительно допустимое изображение; затем асинхронный процесс вне потоков запросов будет обрабатывать каждое изображение по одному. Из-за синхронности библиотеки ImageIO нет никакой выгоды от попытки сделать несколько одновременно. Изображения могут обрабатываться параллельно, учитывая, что библиотека не является синхронной, а только неэффективной.

Хотя выполнение асинхронной обработки добавляет уровень сложности, это, вероятно, хорошая идея в отношении изменения изображения. Что не работает, так это то, что мы не можем обрабатывать исходное изображение в каждом запросе, а это означает, что наша система должна делать предположение, что каждое изображение является допустимыми данными изображения. Когда асинхронный процессор обрабатывает изображение, могут возникнуть несоответствия в системе, если данные неверны.


person user1236874    schedule 29.07.2013    source источник
comment
Вы используете несколько потоков? Вы говорите, что несколько экземпляров JPEGImageReader сериализуются в классе (т.е. однопоточные)? Как вы определили, что это так? Если да, то где монитор, на котором они все блокируются/ожидают?   -  person Jim Garrison    schedule 30.07.2013
comment
Это определенно многопоточность, поскольку в Tomcat это отдельные запросы. Я начинаю верить, что ImageIO создает только один базовый JPEGImageReader под капотом. См.: JPEGImageReader. Мы на 99% уверены, что это именно то, что происходит, потому что, когда мы комментируем часть, которая создает BufferedImage и выполняет преобразование, и просто сохраняем содержимое InputStream на диск, процессоры фактически облагаются налогом. В противном случае они используют около 5% под нагрузкой.   -  person user1236874    schedule 30.07.2013
comment
Похоже, вам нужно спуститься на один уровень в ImageIO и использовать метод, который создает ридеры, а не методы удобства.   -  person user207421    schedule 30.07.2013
comment
Проблема с прямым использованием программ чтения/записи заключается в том, что мне на самом деле нужны некоторые удобные утилиты от ImageIO. Я хочу иметь возможность направить на него входной поток и вернуть проверенное изображение. Если я пойду ниже, я либо буду заблокирован в одном формате, например. JPEG, иначе я перепишу большую часть библиотеки.   -  person user1236874    schedule 30.07.2013
comment
Из ваших данных профилирования (которые могут быть неполными) кажется, что проблема представляет собой серьезную проблему с производительностью в управлении цветом OpenJDK (LCMS). Я думаю, что эта CMS не используется в виртуальных машинах Sun/Oracle. Вы пробовали другие виртуальные машины? Тот факт, что JPEGImageReader внутренне использует синхронизацию для каждого экземпляра, не должен приводить вас к выводу, что ImageIO не может обрабатывать несколько изображений одновременно. Я почти уверен, что может.   -  person Harald K    schedule 02.08.2013


Ответы (2)


Выполняя нагрузочное тестирование, мы поняли, что когда одновременно поступает много запросов, они блокируются в вызове ImageIO.read(). Копнув глубже, мы заметили, что JPEGImageReader синхронизирован и одновременно создается только одно BufferedImage.

Кто-нибудь еще сталкивался с этим?

Как я упоминал в разделе комментариев: Анализ производительности выглядит как проблема с производительностью в системе управления цветом OpenJDK (lcms), потому что преобразование цвета не должно занимать так много времени. Я предполагаю, что без возможности дальнейшей отладки эта проблема делает декодирование (появляется) синхронизированным, даже если ImageIO поддерживает параллельное декодирование.

Вот SSCCE, который показывает, что ImageIO отлично справляется с одновременным декодированием нескольких изображений.

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.event.IIOReadProgressListener;
import javax.imageio.stream.ImageInputStream;
import java.io.File;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

class MultipleJPEGDecoding {
    private static int threads = Runtime.getRuntime().availableProcessors();
    private static ExecutorService executorService = Executors.newFixedThreadPool(threads * 4);

    public static void main(final String[] args) throws InterruptedException {
        for (int i = 0; i < 100; i++) {
            final int index = i;

            executorService.submit(new Runnable() {
                public void run() {
                    try {
                        ImageInputStream stream = ImageIO.createImageInputStream(new File(args[index % args.length]));
                        try {
                            Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);
                            if (!readers.hasNext()) {
                                System.err.println("No reader!");
                                return;
                            }

                            ImageReader reader = readers.next();
                            reader.setInput(stream);
                            reader.addIIOReadProgressListener(new ProgressListener(index));

                            try {
                                reader.read(0);
                            }
                            finally {
                                reader.dispose();
                            }
                        }
                        finally {
                            stream.close();
                        }
                    }
                    catch (Exception e) {
                        System.err.printf("Error reading %d\n", index);
                        e.printStackTrace();
                    }
                }
            });
        }

        executorService.shutdown();
    }

    static class ProgressListener implements IIOReadProgressListener {
        final static AtomicInteger simultaneous = new AtomicInteger(0);

        final int index;
        int nextProgress = 25;

        public ProgressListener(int index) {
            this.index = index;
        }

        public void imageStarted(ImageReader source, int imageIndex) {
            int inProgress = simultaneous.incrementAndGet();
            System.err.printf("Started reading image %d (now decoding %d images simultaneous)...\n", index, inProgress);
        }

        public void imageComplete(ImageReader source) {
            int inProgress = simultaneous.decrementAndGet();
            System.err.printf("Done reading image %d%s.\n", index, inProgress > 0 ? String.format(" (still decoding %d other images)", inProgress) : "");
        }

        public void imageProgress(ImageReader source, float percentageDone) {
            if (percentageDone > nextProgress) {
                int inProgress = simultaneous.get();
                System.err.printf("Progress on image %d (now decoding %d images simultaneous)...\n", index, inProgress);
                nextProgress += 25;
            }
        }

        public void sequenceStarted(ImageReader source, int minIndex) {
        }

        public void sequenceComplete(ImageReader source) {
        }

        public void thumbnailStarted(ImageReader source, int imageIndex, int thumbnailIndex) {
        }

        public void thumbnailProgress(ImageReader source, float percentageDone) {
        }

        public void thumbnailComplete(ImageReader source) {
        }

        public void readAborted(ImageReader source) {
        }
    }
}

Вывод выглядит так:

Started reading image 5 (now decoding 2 images simultaneous)...
Started reading image 0 (now decoding 16 images simultaneous)...
Started reading image 14 (now decoding 15 images simultaneous)...
Started reading image 4 (now decoding 14 images simultaneous)...
Started reading image 13 (now decoding 1 images simultaneous)...
Started reading image 11 (now decoding 13 images simultaneous)...
Started reading image 2 (now decoding 12 images simultaneous)...
Started reading image 15 (now decoding 4 images simultaneous)...
Started reading image 8 (now decoding 11 images simultaneous)...
Started reading image 7 (now decoding 10 images simultaneous)...
Started reading image 9 (now decoding 9 images simultaneous)...
Started reading image 6 (now decoding 8 images simultaneous)...
Started reading image 10 (now decoding 7 images simultaneous)...
Started reading image 1 (now decoding 6 images simultaneous)...
Started reading image 3 (now decoding 5 images simultaneous)...
Started reading image 12 (now decoding 3 images simultaneous)...
Progress on image 11 (now decoding 16 images simultaneous)...
Progress on image 15 (now decoding 16 images simultaneous)...
Progress on image 13 (now decoding 16 images simultaneous)...
Progress on image 13 (now decoding 16 images simultaneous)...
Progress on image 9 (now decoding 16 images simultaneous)...
Progress on image 9 (now decoding 16 images simultaneous)...
Progress on image 1 (now decoding 16 images simultaneous)...
Progress on image 3 (now decoding 16 images simultaneous)...
Progress on image 1 (now decoding 16 images simultaneous)...
Progress on image 3 (now decoding 16 images simultaneous)...
Progress on image 1 (now decoding 16 images simultaneous)...
Progress on image 13 (now decoding 16 images simultaneous)...
Progress on image 5 (now decoding 16 images simultaneous)...
Progress on image 9 (now decoding 16 images simultaneous)...
Progress on image 3 (now decoding 16 images simultaneous)...
Done reading image 3 (still decoding 15 other images).
Started reading image 16 (now decoding 15 images simultaneous)...
Progress on image 11 (now decoding 15 images simultaneous)...
Done reading image 13 (still decoding 14 other images).
Started reading image 17 (now decoding 15 images simultaneous)...
Progress on image 5 (now decoding 15 images simultaneous)...
Progress on image 4 (now decoding 15 images simultaneous)...
Progress on image 11 (now decoding 15 images simultaneous)...
Done reading image 9 (still decoding 14 other images).
Progress on image 5 (now decoding 15 images simultaneous)...
Progress on image 17 (now decoding 15 images simultaneous)...
Done reading image 11 (still decoding 14 other images).
Started reading image 19 (now decoding 15 images simultaneous)...
Progress on image 17 (now decoding 15 images simultaneous)...
Done reading image 5 (still decoding 14 other images).
Started reading image 18 (now decoding 15 images simultaneous)...
Progress on image 15 (now decoding 15 images simultaneous)...
Done reading image 1 (still decoding 14 other images).
Started reading image 21 (now decoding 15 images simultaneous)...
Progress on image 15 (now decoding 15 images simultaneous)...
Progress on image 21 (now decoding 15 images simultaneous)...
Done reading image 15 (still decoding 14 other images).
Progress on image 6 (now decoding 14 images simultaneous)...
Progress on image 21 (now decoding 14 images simultaneous)...
Progress on image 7 (now decoding 14 images simultaneous)...
Progress on image 21 (now decoding 14 images simultaneous)...
Progress on image 7 (now decoding 14 images simultaneous)...
Progress on image 19 (now decoding 14 images simultaneous)...
Progress on image 19 (now decoding 14 images simultaneous)...
Progress on image 7 (now decoding 14 images simultaneous)...
Progress on image 19 (now decoding 14 images simultaneous)...
Done reading image 7 (still decoding 13 other images).
Started reading image 23 (now decoding 14 images simultaneous)...
Progress on image 10 (now decoding 14 images simultaneous)...
Progress on image 23 (now decoding 14 images simultaneous)...
Progress on image 14 (now decoding 14 images simultaneous)...
Started reading image 22 (now decoding 15 images simultaneous)...
Progress on image 0 (now decoding 15 images simultaneous)...
Done reading image 21 (still decoding 14 other images).
Started reading image 24 (now decoding 15 images simultaneous)...
Started reading image 20 (now decoding 16 images simultaneous)...
Progress on image 2 (now decoding 16 images simultaneous)...
Progress on image 8 (now decoding 16 images simultaneous)...
Progress on image 17 (now decoding 15 images simultaneous)...
Done reading image 17 (still decoding 14 other images).
Started reading image 25 (now decoding 15 images simultaneous)...
Progress on image 23 (now decoding 15 images simultaneous)...
Done reading image 19 (still decoding 15 other images).
Started reading image 26 (now decoding 16 images simultaneous)...
Progress on image 23 (now decoding 16 images simultaneous)...
Done reading image 23 (still decoding 15 other images).
Started reading image 27 (now decoding 16 images simultaneous)...
Progress on image 4 (now decoding 16 images simultaneous)...
Progress on image 27 (now decoding 16 images simultaneous)...
Progress on image 27 (now decoding 16 images simultaneous)...
Progress on image 6 (now decoding 16 images simultaneous)...
Progress on image 12 (now decoding 16 images simultaneous)...
Progress on image 20 (now decoding 16 images simultaneous)...
Progress on image 0 (now decoding 16 images simultaneous)...
Progress on image 25 (now decoding 16 images simultaneous)...
Progress on image 25 (now decoding 16 images simultaneous)...
Progress on image 25 (now decoding 16 images simultaneous)...
Progress on image 14 (now decoding 16 images simultaneous)...
Progress on image 10 (now decoding 16 images simultaneous)...
Progress on image 8 (now decoding 16 images simultaneous)...
Progress on image 18 (now decoding 16 images simultaneous)...
Done reading image 25 (still decoding 15 other images).

[...]

Progress on image 75 (now decoding 12 images simultaneous)...
Started reading image 73 (now decoding 13 images simultaneous)...
Progress on image 75 (now decoding 13 images simultaneous)...
Progress on image 73 (now decoding 13 images simultaneous)...
Progress on image 75 (now decoding 13 images simultaneous)...
Started reading image 74 (now decoding 14 images simultaneous)...
Progress on image 66 (now decoding 14 images simultaneous)...
Progress on image 64 (now decoding 14 images simultaneous)...
Progress on image 73 (now decoding 14 images simultaneous)...
Progress on image 60 (now decoding 14 images simultaneous)...
Progress on image 74 (now decoding 14 images simultaneous)...
Progress on image 58 (now decoding 14 images simultaneous)...
Done reading image 75 (still decoding 13 other images).
Progress on image 73 (now decoding 13 images simultaneous)...
Started reading image 77 (now decoding 14 images simultaneous)...
Done reading image 73 (still decoding 13 other images).
Progress on image 77 (now decoding 13 images simultaneous)...
Started reading image 78 (now decoding 14 images simultaneous)...
Progress on image 60 (now decoding 14 images simultaneous)...
Done reading image 48 (still decoding 13 other images).
Progress on image 77 (now decoding 13 images simultaneous)...
Started reading image 79 (now decoding 14 images simultaneous)...
Started reading image 70 (now decoding 15 images simultaneous)...
Progress on image 52 (now decoding 15 images simultaneous)...
Progress on image 71 (now decoding 15 images simultaneous)...
Started reading image 72 (now decoding 16 images simultaneous)...
Progress on image 71 (now decoding 16 images simultaneous)...
Progress on image 54 (now decoding 16 images simultaneous)...
Progress on image 68 (now decoding 16 images simultaneous)...
Progress on image 64 (now decoding 16 images simultaneous)...
Progress on image 66 (now decoding 16 images simultaneous)...
Progress on image 62 (now decoding 16 images simultaneous)...
Progress on image 79 (now decoding 16 images simultaneous)...
Progress on image 79 (now decoding 16 images simultaneous)...
Progress on image 79 (now decoding 16 images simultaneous)...
Progress on image 77 (now decoding 16 images simultaneous)...
Progress on image 68 (now decoding 16 images simultaneous)...
Done reading image 79 (still decoding 15 other images).
Done reading image 77 (still decoding 14 other images).
Started reading image 81 (now decoding 15 images simultaneous)...
Progress on image 74 (now decoding 15 images simultaneous)...
Progress on image 81 (now decoding 15 images simultaneous)...
Progress on image 81 (now decoding 15 images simultaneous)...
Progress on image 78 (now decoding 15 images simultaneous)...
Done reading image 60 (still decoding 14 other images).
Started reading image 82 (now decoding 15 images simultaneous)...
Started reading image 80 (now decoding 16 images simultaneous)...
Progress on image 76 (now decoding 14 images simultaneous)...
Progress on image 66 (now decoding 14 images simultaneous)...
Progress on image 70 (now decoding 14 images simultaneous)...
Done reading image 52 (still decoding 14 other images).
Done reading image 71 (still decoding 15 other images).
Progress on image 81 (now decoding 16 images simultaneous)...
Started reading image 84 (now decoding 15 images simultaneous)...
Started reading image 83 (now decoding 16 images simultaneous)...
Progress on image 58 (now decoding 16 images simultaneous)...
Progress on image 83 (now decoding 16 images simultaneous)...
Progress on image 83 (now decoding 16 images simultaneous)...
Progress on image 83 (now decoding 16 images simultaneous)...
Done reading image 81 (still decoding 15 other images).
Started reading image 85 (now decoding 16 images simultaneous)...
Progress on image 85 (now decoding 16 images simultaneous)...
Progress on image 74 (now decoding 16 images simultaneous)...
Done reading image 66 (still decoding 15 other images).
Started reading image 86 (now decoding 16 images simultaneous)...
Progress on image 64 (now decoding 16 images simultaneous)...
Progress on image 70 (now decoding 16 images simultaneous)...
Progress on image 78 (now decoding 16 images simultaneous)...
Progress on image 54 (now decoding 16 images simultaneous)...
Done reading image 58 (still decoding 15 other images).
Started reading image 87 (now decoding 16 images simultaneous)...
Progress on image 87 (now decoding 16 images simultaneous)...
Progress on image 84 (now decoding 16 images simultaneous)...
Progress on image 87 (now decoding 16 images simultaneous)...
Done reading image 64 (still decoding 15 other images).
Started reading image 88 (now decoding 16 images simultaneous)...
Progress on image 76 (now decoding 16 images simultaneous)...
Done reading image 83 (still decoding 15 other images).
Progress on image 62 (now decoding 15 images simultaneous)...
Progress on image 70 (now decoding 16 images simultaneous)...
Progress on image 85 (now decoding 16 images simultaneous)...
Started reading image 89 (now decoding 16 images simultaneous)...
Progress on image 72 (now decoding 16 images simultaneous)...
Progress on image 85 (now decoding 16 images simultaneous)...
Progress on image 89 (now decoding 16 images simultaneous)...
Done reading image 85 (still decoding 15 other images).
Progress on image 89 (now decoding 15 images simultaneous)...
Progress on image 82 (now decoding 15 images simultaneous)...
Progress on image 80 (now decoding 15 images simultaneous)...
Done reading image 74 (still decoding 14 other images).
Started reading image 91 (now decoding 15 images simultaneous)...
Started reading image 90 (now decoding 16 images simultaneous)...
Done reading image 62 (still decoding 15 other images).
Progress on image 87 (now decoding 15 images simultaneous)...
Progress on image 68 (now decoding 15 images simultaneous)...
Done reading image 87 (still decoding 14 other images).
Progress on image 91 (now decoding 14 images simultaneous)...
Started reading image 93 (now decoding 15 images simultaneous)...
Progress on image 93 (now decoding 15 images simultaneous)...
Progress on image 91 (now decoding 15 images simultaneous)...
Progress on image 91 (now decoding 15 images simultaneous)...
Progress on image 80 (now decoding 15 images simultaneous)...
Started reading image 92 (now decoding 16 images simultaneous)...
Done reading image 91 (still decoding 15 other images).
Started reading image 94 (now decoding 16 images simultaneous)...
Progress on image 93 (now decoding 16 images simultaneous)...
Progress on image 72 (now decoding 16 images simultaneous)...
Progress on image 93 (now decoding 16 images simultaneous)...
Done reading image 93 (still decoding 15 other images).
Started reading image 95 (now decoding 16 images simultaneous)...
Progress on image 95 (now decoding 16 images simultaneous)...
Progress on image 95 (now decoding 16 images simultaneous)...
Progress on image 76 (now decoding 16 images simultaneous)...
Progress on image 95 (now decoding 16 images simultaneous)...
Progress on image 72 (now decoding 16 images simultaneous)...
Done reading image 95 (still decoding 15 other images).
Started reading image 96 (now decoding 16 images simultaneous)...
Progress on image 94 (now decoding 16 images simultaneous)...
Progress on image 89 (now decoding 15 images simultaneous)...
Done reading image 89 (still decoding 14 other images).
Done reading image 54 (still decoding 15 other images).
Started reading image 97 (now decoding 14 images simultaneous)...
Started reading image 98 (now decoding 15 images simultaneous)...
Done reading image 70 (still decoding 13 other images).
Started reading image 99 (now decoding 16 images simultaneous)...
Progress on image 82 (now decoding 16 images simultaneous)...
Progress on image 99 (now decoding 16 images simultaneous)...
Progress on image 99 (now decoding 16 images simultaneous)...
Progress on image 97 (now decoding 16 images simultaneous)...
Progress on image 97 (now decoding 16 images simultaneous)...
Progress on image 97 (now decoding 16 images simultaneous)...
Done reading image 68 (still decoding 15 other images).
Done reading image 97 (still decoding 14 other images).
Progress on image 78 (now decoding 14 images simultaneous)...
Progress on image 99 (now decoding 14 images simultaneous)...
Done reading image 99 (still decoding 13 other images).
Progress on image 86 (now decoding 13 images simultaneous)...
Done reading image 72 (still decoding 12 other images).
Progress on image 82 (now decoding 12 images simultaneous)...
Progress on image 98 (now decoding 12 images simultaneous)...
Progress on image 84 (now decoding 12 images simultaneous)...
Progress on image 90 (now decoding 12 images simultaneous)...
Done reading image 76 (still decoding 11 other images).
Progress on image 92 (now decoding 11 images simultaneous)...
Progress on image 80 (now decoding 11 images simultaneous)...
Progress on image 94 (now decoding 11 images simultaneous)...
Progress on image 88 (now decoding 11 images simultaneous)...
Progress on image 84 (now decoding 11 images simultaneous)...
Progress on image 90 (now decoding 11 images simultaneous)...
Progress on image 92 (now decoding 11 images simultaneous)...
Progress on image 86 (now decoding 11 images simultaneous)...
Progress on image 94 (now decoding 10 images simultaneous)...
Done reading image 84 (still decoding 9 other images).
Progress on image 92 (now decoding 9 images simultaneous)...
Done reading image 78 (still decoding 10 other images).
Progress on image 88 (now decoding 9 images simultaneous)...
Progress on image 90 (now decoding 9 images simultaneous)...
Done reading image 80 (still decoding 8 other images).
Done reading image 82 (still decoding 7 other images).
Progress on image 86 (now decoding 7 images simultaneous)...
Progress on image 96 (now decoding 7 images simultaneous)...
Progress on image 88 (now decoding 7 images simultaneous)...
Done reading image 90 (still decoding 6 other images).
Done reading image 92 (still decoding 5 other images).
Progress on image 98 (now decoding 5 images simultaneous)...
Done reading image 94 (still decoding 4 other images).
Done reading image 86 (still decoding 3 other images).
Progress on image 96 (now decoding 3 images simultaneous)...
Done reading image 88 (still decoding 2 other images).
Progress on image 98 (now decoding 2 images simultaneous)...
Progress on image 96 (now decoding 2 images simultaneous)...
Done reading image 98 (still decoding 1 other images).
Done reading image 96.
person Harald K    schedule 05.08.2013
comment
это ничего не доказывает. все, что вы доказали, это то, что вы можете ставить в очередь запросы к декодеру. вы не доказали, что они расшифровываются одновременно. исходный код класса ясно показывает, что это невозможно. - person pstanton; 06.08.2013
comment
@pstanton В исходном коде говорится, что экземпляр синхронизирован (но в документе API уже указано, что читатели в любом случае не должны совместно использоваться потоками). ImageIO будет использовать разные экземпляры для нескольких вызовов, поэтому он декодирует несколько изображений одновременно (как показывает мой код). Запросы не ставятся в очередь, они одновременно декодируются. Я обновлю код, чтобы сделать его более понятным. - person Harald K; 06.08.2013
comment
я признаю, что не проверял это, но регистрация вызовов вашего кода никогда не покажет, что происходит на самом деле. единственный способ проверить это - поставить точку останова на внутренности JPEGImageReader. я не хочу показаться, что я защищаю свой пост, это не так, я надеюсь, что вы правы. поставьте точку останова на первое попадание в JPEGImageReader.readInternal и посмотрите, остановит ли он все остальные "одновременные" чтения... - person pstanton; 06.08.2013
comment
@pstanton Я не понимаю, что, по вашему мнению, не так с моим кодом? Теперь он сообщает о ходе работы с несколькими изображениями одновременно (я даже написал версию, которая показывает изображения во время декодирования)., код для SO немного длинноват, но, если хотите, протестируйте его). Если я создам точку останова, разве это не приостановит все мои потоки в этой точке останова? Что бы это доказывало? - person Harald K; 06.08.2013
comment
ты совершенно прав. 'threadLock' предназначен для предотвращения доступа разных потоков к разным читателям, а не для того, чтобы разные потоки имели своих собственных читателей. извиняюсь за путаницу. собираюсь удалить свой ответ ;) - person pstanton; 06.08.2013
comment
Хороший улов. Я просмотрел так много этих документов, что подумал, что в них говорится, что из-за утечки памяти или чего-то еще должен быть только один экземпляр этого класса. Это, в сочетании со всеми этими синхронизированными методами, означало бы, что он был бы заблокирован наверняка. Однако вы правы, что должно быть наоборот. Я чувствую, что из-за того, что падение производительности, которое мы наблюдаем, было таким большим, должна иметь место какая-то синхронность, но, возможно, LCMS просто действительно неэффективна. В любом случае, спасибо за ответ! - person user1236874; 07.08.2013
comment
@ user1236874 Также может быть, что реализация LCMS неправильно синхронизирована (что было бы очень плохой идеей для CMS) или что-то подобное. Но трудно сказать без дальнейшего анализа... Вероятно, вы довольны своим асинхронным решением. :-) - person Harald K; 07.08.2013

РЕДАКТИРОВАТЬ: Во-первых, ответ haraldK правильный, а мой первоначальный ответ был неправильным. Однако его нельзя удалить, только отредактировав ОП, следует переназначить галочку.

Механизм ThreadLock предназначен для предотвращения доступа потоков к различным считывателям из их собственных, а не для предотвращения доступа потоков к своим собственным считывателям независимо и одновременно с другими потоками.

Поэтому JPEGImageReader ImageIO должен нормально работать асинхронно.

person pstanton    schedule 29.07.2013
comment
PS я знаю, что это не полное решение, извините за это - person pstanton; 30.07.2013
comment
Это нормально. Если я заработаю, я поставлю вам галочку «Проверить и решить» и обновлю свою проблему решением. Спасибо! - person user1236874; 30.07.2013
comment
Я отмечаю это как правильное, потому что это, насколько я могу судить, самый оптимальный подход. Проблема кроется в OpenJDK, в котором больше нет поддержки JAI, но все остальные найденные мной библиотеки полагаются на ImageIO. - person user1236874; 01.08.2013
comment
@pstanton Если вы внимательно посмотрите на опубликованный вами исходный код, вы увидите, что метод не блокируется при использовании из нескольких потоков. Он выдает IllegalStateException. PS: я действительно думаю, что вы заслуживаете похвалы за свои усилия, помогая ОП найти обходной путь, не поймите меня неправильно. Просто я считаю вывод неверным и пытаюсь избежать путаницы. :-) - person Harald K; 06.08.2013