Потоки блокируются при получении изображения из URL с помощью JAI - PullRequest
0 голосов
/ 07 февраля 2012

Я запускаю службу, которая запускает несколько потоков обработки изображений с использованием JAI.Каждый поток загружает изображение из URL, а затем применяет логику к этому изображению.Потоки застряли (в ожидании) при получении высоты PlanarImage.Любая идея, почему это происходит и как я могу избежать этого?Кроме того, поток, который получил блокировку для объекта (от которого ожидают другие потоки), застревает при чтении сокета.Есть ли время ожидания чтения сокета при чтении изображений с URL?

Код:

public static PlanarImage readImageFromUrl(String url) throws Exception
{
    String urlAddr = URLDecoder.decode(url, Constants.UTF8);
    URL urlS = new URL(urlAddr);

    String operationName = "url";

    ParameterBlockJAI pb = new ParameterBlockJAI(operationName);
    pb.setParameter("URL", urlS);
    pb.setParameter("param", null);

    PlanarImage image = null;
    try
    {
           /** Create a new tilecache object in RenderingHints**/
        image = JAI.create(operationName,pb, (RenderingHints)RenderingHintsFactory.createDefaultRenderingHintsInstance());


        int h = image.getHeight();
        int w = image.getWidth();
        logger.info("Image is "+h +"x"+w+" dim");
        return image;
    }
    catch(Exception e)
    {
        //Release tile cache memory in case of exception
        RenderingHintsFactory.releaseRenderingHints(image);
        throw e;
    }
}

Пример thead, застрявший при ожидании:

"pool-2-thread-97" prio=10 tid=0x0000000050e0b000 nid=0x666d waiting for monitor entry [0x0000000048e74000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.sun.media.jai.codecimpl.JPEGImage.<init>(JPEGImageDecoder.java:105)
- **waiting to lock <0x00000007bca843b8> (a java.lang.Object)**
at com.sun.media.jai.codecimpl.JPEGImageDecoder.decodeAsRenderedImage(JPEGImageDecoder.java:46)
at com.sun.media.jai.opimage.CodecRIFUtil.create(CodecRIFUtil.java:88)
at com.sun.media.jai.opimage.JPEGRIF.create(JPEGRIF.java:43)
at sun.reflect.GeneratedMethodAccessor54.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
at     javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
at com.sun.media.jai.opimage.StreamRIF.create(StreamRIF.java:102)
at sun.reflect.GeneratedMethodAccessor54.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
at         javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
at com.sun.media.jai.opimage.URLRIF.create(URLRIF.java:74)
at sun.reflect.GeneratedMethodAccessor54.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
at     javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
- locked <0x00000007f6a5e3a0> (a javax.media.jai.RenderedOp)
at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
- locked <0x00000007f6a5e3a0> (a javax.media.jai.RenderedOp)
at javax.media.jai.RenderedOp.getHeight(RenderedOp.java:2188)
at com.amazon.lmclassifier.daemon.image.util.ImageUtils.readImageFromUrl(ImageUtils.java:66)

РЕЗЬБА, КОТОРАЯ ЗАБЛОКИРОВАЛА ОБЪЕКТ:

"pool-2-thread-96" prio=10 tid=0x0000000050e08800 nid=0x666c runnable [0x0000000048d72000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
- locked <0x00000007f6af46f0> (a java.io.BufferedInputStream)
at sun.net.www.MeteredStream.read(MeteredStream.java:116)
- locked <0x00000007f6af4718> (a sun.net.www.http.KeepAliveStream)
at java.io.FilterInputStream.read(FilterInputStream.java:116)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:2668)
at com.sun.media.jai.codec.FileCacheSeekableStream.readUntil(FileCacheSeekableStream.java:125)
at com.sun.media.jai.codec.FileCacheSeekableStream.read(FileCacheSeekableStream.java:258)
at com.sun.media.jai.codec.ForwardSeekableStream.read(ForwardSeekableStream.java:54)
at java.io.FilterInputStream.read(FilterInputStream.java:116)
at sun.awt.image.codec.JPEGImageDecoderImpl.readJPEGStream(Native Method)
- locked <0x00000007f6af47e8> (a sun.awt.image.codec.JPEGImageDecoderImpl)
at sun.awt.image.codec.JPEGImageDecoderImpl.decodeAsBufferedImage(JPEGImageDecoderImpl.java:210)
- locked <0x00000007f6af47e8> (a sun.awt.image.codec.JPEGImageDecoderImpl)
at com.sun.media.jai.codecimpl.JPEGImage.<init>(JPEGImageDecoder.java:110)
**- locked <0x00000007bca843b8> (a java.lang.Object)**
at com.sun.media.jai.codecimpl.JPEGImageDecoder.decodeAsRenderedImage(JPEGImageDecoder.java:46)
at com.sun.media.jai.opimage.CodecRIFUtil.create(CodecRIFUtil.java:88)
at com.sun.media.jai.opimage.JPEGRIF.create(JPEGRIF.java:43)
at sun.reflect.GeneratedMethodAccessor54.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
at javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
at com.sun.media.jai.opimage.StreamRIF.create(StreamRIF.java:102)
at sun.reflect.GeneratedMethodAccessor54.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
at javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
at com.sun.media.jai.opimage.URLRIF.create(URLRIF.java:74)
at sun.reflect.GeneratedMethodAccessor54.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.media.jai.FactoryCache.invoke(FactoryCache.java:122)
at javax.media.jai.OperationRegistry.invokeFactory(OperationRegistry.java:1674)
at javax.media.jai.ThreadSafeOperationRegistry.invokeFactory(ThreadSafeOperationRegistry.java:473)
at javax.media.jai.registry.RIFRegistry.create(RIFRegistry.java:332)
at javax.media.jai.RenderedOp.createInstance(RenderedOp.java:819)
- locked <0x00000007f6af49e0> (a javax.media.jai.RenderedOp)
at javax.media.jai.RenderedOp.createRendering(RenderedOp.java:867)
- locked <0x00000007f6af49e0> (a javax.media.jai.RenderedOp)
at javax.media.jai.RenderedOp.getHeight(RenderedOp.java:2188)
at com.amazon.lmclassifier.daemon.image.util.ImageUtils.readImageFromUrl(ImageUtils.java:66)
‹ ImageReader thread safety Threads getting blocked while fetching image from url › 

Я выяснил из какого-то другого поста, что JPEGImageDecoder.java использует объект мьютекса для синхронизации чтения изображений.И поэтому потоки блокируются.http://www.java.net/node/677181 Есть идеи, как мне решить эту проблему?

1 Ответ

0 голосов
/ 07 февраля 2012

В некоторых случаях загрузка изображений происходит в фоновом режиме, пока не будет вызван getHeight() или getWidth(), которые затем ждут завершения загрузки. Нужно просто отложить использование изображения до точки в будущем.

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

...