首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java PipedInputStream线程处于阻塞状态,没有其他线程持有锁?

Java PipedInputStream线程处于阻塞状态,没有其他线程持有锁?
EN

Stack Overflow用户
提问于 2017-05-30 09:34:59
回答 2查看 1.2K关注 0票数 0

我使用apache客户端向目标服务器执行一些post请求,使用管道流编写内容。因此,基本上,从一个线程,http客户机从PipedInputStream读取,从另一个线程,我在PipedOutputStream上编写内容。

每隔一段时间,我就会看到线程转储,并看到许多线程在java.io.PipedInputStream.read()方法上被阻塞,执行wait(1000)行。阻塞状态意味着读取线程在1000 ms运行后等待获取锁。但我不明白的是,为什么我看不到任何写线程来保存线程转储中的锁。我遗漏了什么,如何避免线程被阻塞?

下面是线程转储文件中的一些行:

代码语言:javascript
复制
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)
EN

回答 2

Stack Overflow用户

发布于 2017-05-30 09:53:06

当您在一个read()上调用PipedInputStream并且缓冲区为空时,它将在某个对象上阻塞wait(),直到对应的PipedOutputStream写入一些东西并通知PipedInputStream正在等待的任何对象。这只是熟悉的

代码语言:javascript
复制
synchronized (lock)
{
    while (...)
        lock.wait();
}

模式,其中wait()为其他人释放锁,以便同步并通知on。

为什么你要使用管道流,这是另一个谜。他们只是个玩具。

票数 1
EN

Stack Overflow用户

发布于 2017-05-30 09:51:21

当您在InputStream上调用read时,它会等到OutputStream最终得到数据。所以你才会有等着的家伙。因此,它不是关于写入和锁定,而是关于读取和等待,而inputStream将有数据。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44258603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档