Future.get(超时)的基础线程行为 [英] Underlying thread behavior with Future.get(timeout)

查看:235
本文介绍了Future.get(超时)的基础线程行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We are using Future with a timeout to accomplish a task. We get a TimeOutException when time limit exceeds. From the behavior of thread dump, I realize that underlying thread continues.

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

Is it the case? How does it take care of multiple threads roaming around? What if no IOException is thrown for the thread which was removed from the pool?

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

If this is true, what is the way to kill underlying thread. It keeps on waiting for an external IO in my case.

线程转储的一部分:

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(对于循环中的任何任务),我们取消这样的任务:

Once TimeOutException occurs (for any task in the loop), we cancel the tasks like this:

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

不应该解决问题吗?

请建议。

提前致谢。

推荐答案

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

Yes, it's the case that your thread continues and executed task is unaffected. TimeoutException indicates that you didn't get the result in the appropriate time.

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

If you want to interrupt underlying thread you can handle the exception and use cancel(true) method from the used implementation of Future.

编辑

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

I missed the case that your thread is waiting on a blocking I/O as your stack trace explains. Thread.interrupt() which is called from future.cancel(true) won't help in this case.

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

The common pattern in this situtation is to close underlying input stream. I'm not very familiar with javax.imageio package but there is an overloaded method on ImageIO which accepts the InputStream. You might want to store it somewhere and later close it on timeout.

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

It will call close() on SocketInputStream which in its turn will call close() method of underlying Socket which is waiting for blocking read to complete. An executing thread which is blocked in an I/O operation (as per your trace) upon this socket will stop waiting for EOF with SocketException.

这篇关于Future.get(超时)的基础线程行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆