2017-05-30 5 views
0

私はapache httpクライアントを使用して、パイプでストリームを使用してコンテンツを書き込む、いくつかの投稿要求をターゲットサーバに実行しています。ですから、基本的には、あるスレッドのHTTPクライアントはPipedInputStreamから読み込み、別のスレッドからはPipedOutputStreamのコンテンツを書きます。Java PipedInputStreamスレッドは、ロックを保持している他のスレッドがないBLOCKED状態ですか?

毎回、スレッドダンプを取得していて、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) 

答えて

-1

あなたがたInputStreamで読む呼び出すときのOutputStreamは、最終的にデータを取得するまでは待機します:ここで

は、スレッドダンプファイル内からいくつかの行があります。だからこそ、あなたはブロークを待っています。したがって、それは書き込みとロックではなく、inputStreamにデータがある間は読み込みと待機に関するものです。あなたはPipedInputStreamread()を呼び出すと、バッファが空になると、対応するPipedOutputStreamが何かとPipedInputStreamが待機しているオブジェクトどんな通知を書き込むまで

+0

データがない場合、読み取りスレッドは読み取りメソッド内でwhileループを実行しているか、そのループ内からwait(long)を実行中であるため、 'RUNNABLE'または' TIMED_WAITING'状態になります。 'BLOCKED'状態にあるということは、他のスレッドがそのロックを持っていることを意味しますが、スレッドダンプにそのような書き込みスレッドはありません。 –

+0

出力ストリームは「データを取得」しません。また、inputStreamにデータがある間は読み書き待ちではありません。それはどういう意味ですか、間違っているのか、この答えはわかりにくく、分かりやすいところでは間違っています。 – EJP

0

、それはいくつかのオブジェクトにwait()にブロックします。これはwait()同期との通知する他の誰かのためにロックを解除するだけでお馴染みの

synchronized (lock) 
{ 
    while (...) 
     lock.wait(); 
} 

パターン、です。

なぜパイプラインを使用しているのかは別の謎です。彼らはおもちゃだけです。

+0

バッファが空の場合、ダンプ内の読み取りスレッドの状態は 'TIMED_WAITING'で' BLOCKED'になります。そして、 'PipedInputStream'から待っているbtwはタイムアウトしています。そのタイムアウトが終了すると、読み込みスレッドはwaitメソッドを実行して解放されたロックを取り戻そうとしています。取り込めない場合は、ロック状態になります。成功すれば 'RUNNIGN'状態になります。これは奇妙です。これは、そのロックを保持している別のスレッド(書き込みスレッド)があるはずですが、そのスレッドのトレースにはトレースがないことを意味します。 –

+0

私は 'apache mina'の上にあるプロキシのhttpサーバに取り組んでいます。したがって、このサーバーは一連のバイトを受信して​​おり、httpオブジェクトでそれらをデコードし、ターゲットサーバーへの別の要求を作成して実行します。したがって、スレッド内では、リクエスト内の 'PipedInputStream'をラップする' apache httpclient'を使用してターゲットサーバへのストリームを開き、 'PipedOutputStream'を使用してデータをポンピングしている別のスレッドからストリームを開きます。 –

+0

これは、最初にパイプストリームを使用する理由を説明していません。私はそれらを1997年に一度だけ使用し、ほとんど直ちに削除しました。 – EJP

関連する問題