如何在Java中使一个函数具有“超时”功能?

3
private String indexPage(URL currentPage) throws IOException {
    String content = "";
    is = currentPage.openStream();
    content = new Scanner( is ).useDelimiter( "\\Z" ).next();
    return content;
}

这是我目前用于爬取网页的功能。存在一个问题,即:
content = new Scanner( is ).useDelimiter( "\\Z" ).next();

如果网页没有响应或响应时间过长,我的线程就会卡在上面的那一行。如果它需要超过5秒才能完全加载该流,最简单的方法是中止此函数吗?
提前感谢!

使用“timeoutable”加1分 - Davie
5个回答

7

如果您不想费力地使用单独的监视线程,那么在网络连接上启用连接和读取超时可能已经足够了(尽管不完全符合您的要求)。例如:

URL url = new URL("...");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setReadTimeout(10000);
InputStream is = conn.getInputStream();

如果连接服务器需要超过5秒(5000毫秒),或者在实际读取的任何内容块之间需要等待超过10秒(10000毫秒),则此示例将失败。但是它不限制您检索页面所需的总时间。


3

您可以从另一个线程关闭流。


3

谷歌最近发布的 guava-libraries 中有一些类提供了类似的功能:

TimeLimiter

生成代理对象,对代理对象的方法调用施加时间限制。例如,要返回 target.someMethod() 的值,但如果此方法调用超过 50 毫秒,则替换为 DEFAULT_VALUE,您可以使用以下代码...


1

0
尝试中断线程;Java中的许多阻塞调用在接收到中断时将继续执行。
在这种情况下,content应为空,Thread.isInterrupted()应为true

通常I/O是不可中断的。 Solaris上的某些版本的Sun JRE曾经这样做,但我不知道任何其他默认启用它的版本。 - Tom Hawtin - tackline

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接