我正在使用 apache http客户端对目标服务器执行一些发布请求,使用管道流编写内容。所以,基本上,从一个线程http客户端正在从PipedInputStream
和另一个线程中读取我在PipedOutputStream
上写的内容。
每隔一段时间我就会在执行java.io.PipedInputStream.read()
行的wait(1000)
方法中获得线程转储并看到许多线程被阻塞。 BLOCKED 状态表示读取线程在1000 ms
过去后等待获取锁定。但我不明白的是为什么我看不到任何写入线程来保存线程转储中的锁。我错过了什么,如何避免线程被阻止?
以下是线程转储文件中的一些行:
Thread 7912: (state = BLOCKED)
- java.lang.Object.wait(long) @bci=0 (Compiled frame; information may be imprecise)
- java.io.PipedInputStream.read() @bci=142, line=326 (Compiled frame)
- java.io.PipedInputStream.read(byte[], int, int) @bci=43, line=377 (Compiled frame)
- org.apache.http.entity.InputStreamEntity.writeTo(java.io.OutputStream) @bci=75, line=140 (Compiled frame)
- org.apache.http.impl.execchain.RequestEntityProxy.writeTo(java.io.OutputStream) @bci=10, line=123 (Compiled frame)
- org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(org.apache.http.HttpEntityEnclosingRequest) @bci=31, line=156 (Compiled frame)
- org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(org.apache.http.HttpEntityEnclosingRequest) @bci=5, line=162 (Compiled frame)
- org.apache.http.protocol.HttpRequestExecutor.doSendRequest(org.apache.http.HttpRequest, org.apache.http.HttpClientConnection, org.apache.http.protocol.HttpContext) @bci=223, line=238 (Compiled frame)
- org.apache.http.protocol.HttpRequestExecutor.execute(org.apache.http.HttpRequest, org.apache.http.HttpClientConnection, org.apache.http.protocol.HttpContext) @bci=25, line=123 (Compiled frame)
- org.apache.http.impl.execchain.MainClientExec.execute(org.apache.http.conn.routing.HttpRoute, org.apache.http.client.methods.HttpRequestWrapper, org.apache.http.client.protocol.HttpClientContext, org.apache.http.client.methods.HttpExecutionAware) @bci=714, line=271 (Compiled frame)
- org.apache.http.impl.execchain.ProtocolExec.execute(org.apache.http.conn.routing.HttpRoute, org.apache.http.client.methods.HttpRequestWrapper, org.apache.http.client.protocol.HttpClientContext, org.apache.http.client.methods.HttpExecutionAware) @bci=447, line=184 (Compiled frame)
- org.apache.http.impl.execchain.RetryExec.execute(org.apache.http.conn.routing.HttpRoute, org.apache.http.client.methods.HttpRequestWrapper, org.apache.http.client.protocol.HttpClientContext, org.apache.http.client.methods.HttpExecutionAware) @bci=39, line=88 (Compiled frame)
- org.apache.http.impl.client.InternalHttpClient.doExecute(org.apache.http.HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) @bci=168, line=184 (Compiled frame)
- org.apache.http.impl.client.CloseableHttpClient.execute(org.apache.http.client.methods.HttpUriRequest, org.apache.http.protocol.HttpContext) @bci=14, line=82 (Compiled frame)
- org.apache.http.impl.client.CloseableHttpClient.execute(org.apache.http.client.methods.HttpUriRequest) @bci=6, line=107 (Compiled frame)
答案 0 :(得分:0)
当您在synchronized (myList) {
try {
while (myList.size() == 0) {
myList.wait();
}
Object elem = myList.removeLast();
} catch (Exception e) {
e.printStackTrace();
}
}
上调用read()
并且缓冲区为空时,它将阻塞某个对象的PipedInputStream
,直到相应的wait()
写入内容并通知任何对象PipedOutputStream
正在等待。这只是熟悉的
PipedInputStream
模式,其中synchronized (lock)
{
while (...)
lock.wait();
}
释放锁,供其他人同步和通知。
为什么你根本使用管道流是另一个谜。它们只是一种玩具。
答案 1 :(得分:-1)
当您在InputStream上调用read时,它将一直等到OutputStream最终获取数据。这就是你等待blokcs的原因。所以,它不是关于编写和锁定,而是关于读取和等待,而inputStream将有数据。