使用JAI从URL获取图像时线程被阻塞

时间:2012-02-07 07:29:04

标签: java multithreading jai

我正在运行一个服务,它使用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 :(得分:0)

在某些情况下,图像加载会在后台延迟发生,直到调用getHeight()getWidth(),然后等待加载完成。人们只需要将图像推迟到将来使用。

为了减少问题,您可以先从网络加载文件,然后从本地文件系统加载它们作为图像。这也可以表明进展。