Future.get(超时)的基础线程行为

时间:2013-01-15 06:21:02

标签: java multithreading threadpool future futuretask

我们正在使用Future超时来完成任务。我们在时间限制超过时获得TimeOutException。从thread dump的行为,我意识到底层线程仍在继续。

是这样的吗?如何处理漫游的多个线程? 如果从池中删除的线程没有抛出IOException该怎么办?

如果这是真的,那么kill底层线程的方式是什么。在我的情况下,它一直在等待外部IO

线程转储的一部分:

Thread 29587: (state = IN_NATIVE)
 - java.net.SocketInputStream.socketRead0(java.io.FileDescriptor, byte[], int, int, int) @bci=0 (Compiled frame; information may be imprecise)
 - java.net.SocketInputStream.read(byte[], int, int) @bci=84, line=129 (Compiled frame)
 - java.io.BufferedInputStream.fill() @bci=175, line=218 (Compiled frame)
 - java.io.BufferedInputStream.read1(byte[], int, int) @bci=44, line=258 (Compiled frame)
 - java.io.BufferedInputStream.read(byte[], int, int) @bci=49, line=317 (Compiled frame)
 - sun.net.www.MeteredStream.read(byte[], int, int) @bci=16, line=116 (Compiled frame)
 - java.io.FilterInputStream.read(byte[], int, int) @bci=7, line=116 (Compiled frame)
 - sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(byte[], int, int) @bci=4, line=2672 (Compiled frame)
 - javax.imageio.stream.FileCacheImageInputStream.readUntil(long) @bci=64, line=121 (Compiled frame)
 - javax.imageio.stream.FileCacheImageInputStream.read(byte[], int, int) @bci=69, line=167 (Compiled frame)
 - com.sun.imageio.plugins.jpeg.JPEGImageReader.readImageHeader(long, boolean, boolean) @bci=0 (Compiled frame)
 - com.sun.imageio.plugins.jpeg.JPEGImageReader.readNativeHeader(boolean) @bci=12, line=532 (Compiled frame)
 - com.sun.imageio.plugins.jpeg.JPEGImageReader.checkTablesOnly() @bci=92, line=277 (Compiled frame)
 - com.sun.imageio.plugins.jpeg.JPEGImageReader.gotoImage(int) @bci=41, line=409 (Compiled frame)
 - com.sun.imageio.plugins.jpeg.JPEGImageReader.readHeader(int, boolean) @bci=2, line=525 (Compiled frame)
 - com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(int, javax.imageio.ImageReadParam, boolean) @bci=3, line=968 (Compiled frame)
 - com.sun.imageio.plugins.jpeg.JPEGImageReader.read(int, javax.imageio.ImageReadParam) @bci=8, line=948 (Compiled frame)
 - javax.imageio.ImageIO.read(javax.imageio.stream.ImageInputStream) @bci=55, line=1422 (Compiled frame)
 - javax.imageio.ImageIO.read(java.net.URL) @bci=42, line=1374 (Compiled frame)

一旦发生TimeOutException(对于循环中的任何任务),我们取消这样的任务:

for(Entry<Requests, Future<?>> futureTask : futureTasks.entrySet())
                {
                    Future<?> future = futureTask.getValue();
                    if(!future.isDone() || future.isCancelled())
                    {
                        future.cancel(true);
                        }
                }

不应该解决问题吗?

请建议。

提前致谢。

1 个答案:

答案 0 :(得分:2)

是的,你的线程继续执行,执行任务不受影响。 TimeoutException 表示您未在适当的时间内获得结果。

如果要中断底层线程,可以处理异常,并使用 Future 中使用的 Future 方法中的 cancel(true)方法。

修改

我错过了你的线程正在等待阻塞I / O的情况,因为你的堆栈跟踪解释了。在这种情况下,从 future.cancel(true)调用的 Thread.interrupt()将无济于事。

此参与中的常见模式是关闭基础输入流。我对 javax.imageio 包不是很熟悉,但 ImageIO 上有一个重载方法,它接受 InputStream 。您可能希望将其存储在某处,然后在超时时将其关闭。

它将在 SocketInputStream 上调用 close(),而 SocketInputStream 将调用底层 Socket的 close()方法等待阻塞读取完成。在此套接字上的I / O操作(根据您的跟踪)阻塞的执行线程将停止等待EOF,并使用 SocketException