遵循我的代码:
if (is != null) {
while (is.available() == 0) {
}
firstDataPackageEnd = System.currentTimeMillis();
int count = 0;
String sdf = null;
int length = 0;
int acceptLenth = 0;
Boolean firstRead = false;
int headEnd = 0;
while ((count = is.available()) > 0
|| (this.transferKind == TRANSFER_END_SPECIAL_LENGTH ? length < acceptLenth
: headEnd < 2)) {
/* System.out.println("允许通过的:" + acceptLenth);
System.out.println("已经有:" + length);
System.out.println("有结尾标志:" + headEnd);
*/ length = length + count;
byte[] b = new byte[count];
is.read(b);
sdf = new String(b, "utf-8");
sb.append(sdf);
if (sdf.indexOf("\r\n\r\n") != -1) {
headEnd++;
}
if (!firstRead) {
Matcher matcher = CONTENT_LENGTH_PATTERN.matcher(sdf);
if (matcher.find()) {
acceptLenth = Integer.parseInt(matcher.group(1));
firstRead = true;
this.transferKind = TRANSFER_END_SPECIAL_LENGTH;
} else {
Matcher trunkMatcher = TRANSFER_ENCODING_PATTERN
.matcher(sdf);
if (trunkMatcher.find()) {
String encode = trunkMatcher.group(1);
if ("chunked".equals(encode)) {
acceptLenth = Integer.MAX_VALUE;
this.transferKind = TRANSFER_END_TRANKED;
firstRead = true;
}
}
}
}
}
当我多次运行该线程时,大约2个小时后,我无法得到我期望的结果,所以我有一个java堆栈转储:
"crawling_thread_socketwatchdog_0" #18 daemon prio=5 os_prio=0
tid=0x00007fb97c3da800 nid=0x605 runnable [0x00007fb965513000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAvailable(Native Method)
at java.net.AbstractPlainSocketImpl.available(AbstractPlainSocketImpl.java:490)
- locked <0x00000000c55bd3d0> (a java.net.SocksSocketImpl)
at java.net.SocketInputStream.available(SocketInputStream.java:258)
at net.health39.socketmonitor.monitor.AbstractHttpMonitor.testSocketConnectServer(AbstractHttpMonitor.java:67)
at net.health39.socketmonitor.monitor.impl.HttpSocketDirectMonitor.startHttpConnect(HttpSocketDirectMonitor.java:23)
at net.health39.crawlingprovider.WebWatchdogImplBySocketProvider.crawl(WebWatchdogImplBySocketProvider.java:141)
at net.health39.crawlingengine.core.HttpProxyCrawlingProviderBase.crawl(HttpProxyCrawlingProviderBase.java:52)
at net.health39.crawlingengine.core.CrawlingProviderBase.doCrawlingLoop(CrawlingProviderBase.java:189)
at net.health39.crawlingengine.core.MultiThreadInitializer$CrawlingWorkerThread.run(MultiThreadInitializer.java:40)
我非常惊讶,它阻止,并且它一直在运行,从信息我猜它阻塞在count = is .available();
有人可以帮助我,(提示:我是中国人,我的英语不是很标准,非常抱歉)
答案 0 :(得分:-1)
为什么JDK说
InputStream.available()
无法阻止
你误解了这一点。它实际上说的是
返回对此输入流可以读取(或跳过)的字节数的估计值,而不会被下一次调用此输入流的方法阻塞。
操作词是'可以阅读......没有阻塞'。这是不会阻止的读取。
但无论如何都是如此。
阻止
不,不。你是在一个没有头脑的旋转循环中调用它。删除两个available()
调用,使用合理的缓冲区大小,然后阅读。