3

I/O 操作によってブロックされているスレッドを中断する方法を本当に知りたいですか? I/O はソケットを介して行われますが、ソケットを使用したくありませんclose()

を使用してスレッドを中断しようとしThread.interrupt()ましたが、成功しませんでした。

IO 操作によってスレッドがブロックされました:

void run(){
    byte[] data=new byte[1024];
    in.read(data);//blocked!
}

ブロックされたスレッドを中断するスレッド (機能しませんでした):

void run(){
    blockedThread.interrupt();//no success!
}
4

7 に答える 7

3

Socket通常の Javaクラスを使用してソケットを閉じることができない、または閉じたくない場合は、 java.nio.SocketChannelを使用してソケットを操作できます。

SocketChannelソケットの I/O を待機しているスレッドを中断することで閉じることができるInterruptibleChannelを実装します。この場合、ブロックされた読み取りはClosedByInterruptExceptionをスローします。

于 2013-10-17T20:13:12.270 に答える
2

ブロッキング IO 操作は IOException をスローするため、次のようなメソッドを追加できます。

public void close() throws IOException {
    this.socket.close();
}

javadoc から:-

このソケットを閉じます。現在 accept() でブロックされているスレッドは、SocketException をスローします。

于 2013-10-17T19:58:40.737 に答える
1

このブログ投稿、特にSolution 4 – NIO with Buffering をご覧ください。

要するに:通常のファイルの場合は、 を使用する必要があり、拡張NIOする aを使用します。.ChannelAbstractInterruptableChannelFileChannel

ソケットを使用する場合はSocket#close()、割り込み/クローズに使用します。

javadocsによると:

このソケットの I/O 操作で現在ブロックされているスレッドは、SocketException をスローします。

しかし:

この問題を回避する別の方法があります。 で非同期 IO を使用NIOしてください。非同期 IO の問題は、(ブロッキング IO と比較して) 処理が非常に複雑であることです。これは、ストリームではなくバッファーを中継するためです。

于 2013-10-17T20:28:52.757 に答える
1

残念ながら、ほとんどのプラットフォームの Sun Java impl は、スレッド割り込みによる io 割り込みを処理しません (nio の一部でこれを取得できると思いますが、不明です)。ただし、スレッドがソケットからの読み取りをブロックされていて、そのソケットへのハンドルがある場合は、別のスレッドからソケットを非同期に閉じることができます (ブロックされたスレッドを中断します)。

于 2013-10-17T19:57:10.683 に答える
1

InterruptedExceptionスローされると宣言されていないことに注意してください。

読んだ

public int read(byte[] b)
         throws IOException

入力ストリームからいくつかのバイトを読み取り、それらをバッファ配列 b に格納します。実際に読み取られたバイト数は整数として返されます。このメソッドは、入力データが使用可能になるか、ファイルの終わりが検出されるか、例外がスローされるまでブロックされます。

一部の読み取りメソッドは、 を介して外部割り込みに応答しThread#interrupt()、ストリームを閉じるか、例外をスローします。

何らかの方法で別のスレッドからストリームを閉じるかフィードするか、または でスレッドを強制終了しない限り、このスレッドを停止することはできませんThread#stop()。この最後の方法は最後の手段にすぎず、さまざまな理由で使用しないでください。

于 2013-10-17T19:57:18.683 に答える
1

モニターを待っている操作のような I/O は中断InterruptedExceptionできないため、これらのケースではルーチンは必要ありませんが、パッケージJava 7 Documentation に属する I/O クラスによれば、nio割り込みスローの試みに応答できます。ストリーム中断例外の 1 つは、これの 1 つでありClosedByInterruptionException、その親クラスAsynchronousCloseExceptionです。

ただし、ストリームを閉じるのではなく、実行スレッドを閉じたい場合は、FutureTaskキャンセルする方法を提供することを検討できます。

于 2013-10-17T20:11:56.900 に答える