2011-07-21 19 views
2

タイムアウトで外部プロセスを実行しようとしていて、生成されたすべての出力を読み込もうとしています。これは驚くほど愉快な仕事であることが証明されています。私の基本的な戦略は、ProcessBuilderを使用してプロセスを開始し、メインスレッドでその出力を読み取ることです。タイムアウトが期限切れになるのを待つ別のスレッドは、私が渡したReadableByteChannelのclose()を呼び出し、それに渡されたプロセスのdestroy()も呼び出します。ReadableByteChannel.close()をブロックする原因は何ですか?

これは、予期しないAsynchronousCloseExceptionを取得しても、無限の出力をプリントするプロセスでうまく機能しているようです。しかし、ちょうど近くに無限のスレッドブロックを眠るプログラムに対してテストする場合:

private void terminateProcess() { 
    try { 
     System.out.println("About to close readChannel."); 
     readChannel.close(); 
     System.out.println("Closed the readChannel."); 
    } catch (IOException e) { 
     // Not relevant 
    } 
} 

私は2番目のprint文を見ることはないと私のテストは永遠にハングアップします。 javadocは、close()は、別のcloseが動作中であればブロックすることができますが、私のコードでclose()を呼び出すことは他にありません。それ以外に何ができるのでしょうか?

答えて

3

テストが永久にハングする理由は、ReadableByteChannel.read()がそれをブロックしている場合、ReadableByteChannel.close()がブロックするということです。

ドキュメントから、ブロックモードのReadableByteChannel(デフォルトではすべてのチャネル)は、ByteBufferに空きがある場合に少なくとも1バイトが読み込まれるまでブロックされ、読み込みがブロックされます。

クラスjava.nio.channels.Channels $ ReadableByteChannelImpl(Channels.javaにあります)のコードを読んでいると、ReadableByteChannelImplが「本当に中断できません」とコメントされていることがわかります。

Process.destroy()を呼び出すと、入力が生成されなかったプロセスが終了し、読み取りスレッドからAsynchronousCloseExceptionがスローされます。

+0

正解、ありがとうございます。私はclose *の後にdestroy *を呼び出していましたが、これは記述したすべての理由で失敗しました。私はAPIが正確に真実を伝えていないことに少し失望していますが、私は結果を議論することはできません。 –

+0

@ Josh Gagnon ReadableByteChannelのAPIドキュメントでは、 '他の種類の入出力操作が読み取り操作と並行して進行するかどうかは、チャンネルの種類によって異なります。 – EJP

関連する問題