在 Java 中,线程挂在 SocketRead0 中,我该怎么办?

Posted

技术标签:

【中文标题】在 Java 中,线程挂在 SocketRead0 中,我该怎么办?【英文标题】:In Java, thread hangs in SocketRead0, what can I do? 【发布时间】:2011-09-27 06:49:59 【问题描述】:

我正在开发一个网络爬虫,但通常在执行短时间(几分钟)后,一些线程会停止工作。运行调试器,发现它停在了SocketRead0中。

当线程将下载带有HttpURLConnection.getInputStream() 的页面内容时会发生这种情况。

我不知道是什么原因造成的,但我认为这与多线程有关。

有人知道如何解决或避免这种情况吗?

我还没有使用 HttpURLConnection 池,因为我不知道该怎么做。

conn = (HttpURLConnection) new URL(url).openConnection();
conn.setInstanceFollowRedirects(true);
conn.connect();
CountingInputStream content;

try 
    content = new CountingInputStream(conn.getInputStream());
    //processing of content
    content.close();
    return true;
     catch (Exception e) 
        return false;
    

【问题讨论】:

首先发布一些代码 - 没有人可以看到你做了什么,所以没有人可以提出修复建议。 爬取线程是否可能实际上正在等待来自远程服务器的数据?我会用 NIO 来做这些事情。 @duffymo 我添加了一些代码。连接打开到服务器,线程停止在conn.getInputStream() 我正在使用 HttpURLConnection 开发网络爬虫。忘了它。至于您的问题,您可以等待连接超时或调用 Thread.interrupt @bestsss 你推荐使用什么? 【参考方案1】:

您需要在连接上设置套接字读取超时。这将导致它在指定的时间段后抛出异常而不是挂起。

http://download.oracle.com/javase/1.5.0/docs/api/java/net/URLConnection.html#setReadTimeout(int)

【讨论】:

工作,但是线程在打开与服务器的连接时挂起,而不是在阅读时,所以我使用了setConnectTimeout()。非常感谢。【参考方案2】:

您正在使用的服务器可能没有按照您的预期发送数据,并且您的线程在等待数据时被阻塞。

您使用的原始java.io.* 类是一个阻塞 I/O 实现,这意味着如果没有数据可供读取,像InputStream.read() 这样的方法将停止线程 - 调用等待直到有数据,如果到达,方法返回。

在 Java 1.4 中,添加了 java.nio 包,这是一个非阻塞 I/O 实现。如果您使用的服务器可能无法可靠地提供服务,我建议您使用它。 Here are some examplesnio的使用方法。

【讨论】:

太麻烦了,只为超时切换到nio。 io 也有超时设置。

以上是关于在 Java 中,线程挂在 SocketRead0 中,我该怎么办?的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 Java 中的 SocketInputStream.socketRead0 挂起?

socketRead0(FileDescriptor, byte[], int, int, int)

SocketInputStream.socketRead0() 中 CPU 使用率高的原因

Pthread Mutex 挂在一个线程中

记录一个使用HttpClient过程中的一个bug

使用java读取URL时读取超时错误