2010-12-13 10 views
61

Javaのコンテキストでは、GUIウィンドウを開いたときにネットワーク入力を読み込むための新しいスレッドを作成します。ウィンドウを閉じると、ソケットリソースを解放してすぐにスレッドを終了します。今私はsetSoTimeoutメソッドを使用していますが、私はタイムアウトの例外を待つことを望んでいません。誰か提案をしてもらえますか?ありがとう!ソケットIO操作でスレッドブロッキングを即座に終了する方法はありますか?

+11

これは-1を得た理由を私は理解していませんか?!?私は質問がかなり明確で現場にあったと思う。 –

答えて

53

これを行うには(潜在的に)3つの方法があります。

  • がソケットにSocket.close()を呼び出すと、ストリーム操作に関連するInputStreamOutputStreamオブジェクトを閉じ、任意のスレッドがソケットでブロックされたり(関連する)が発生しますブロックされません。 javadocによると、ソケット自体の操作はSocketExceptionです。

  • Thread.interrupt()(特定の状況では指定されていない)を呼び出すと、ブロッキングI/O操作が中断され、InterruptedIOExceptionがスローされます。

    警告に注意してください。明らかに、 "interrupt()"アプローチは、 "ほとんどの"現代のJavaプラットフォームでは機能しません。 (他の誰かが時間と傾きを持っていれば、このアプローチがうまくいく状況を調査することも可能ですが、プラットフォーム特有の動作であるという事実だけで、アプリケーションが必要な場合にのみ使用してください特定のプラットフォーム上で動作するように。あなたは簡単に自分のために「それを試す」ことができ、その時点で。)

  • これを行うことは可能第三の方法は、Socket.shutdownInput()および/またはSocket.shutdownOutput()を呼び出すことです。 javadocは、現在ブロックされている読み書き操作で何が起こるかを明示的に述べていませんが、ブロック解除して例外をスローすると考えるのは不合理ではありません。しかし、javadocが何が起こっているのかを言わないならば、その振る舞いはプラットフォーム特有であると仮定されるべきです。

+1

どのような状況でthread.interrupt()がブロックI/O操作を中断しますか? –

+2

Xu DXn - 文書化されていません。一部のストリームはこれを実装しますが、他のストリームは実装しません。詳細については、OpenJDKのソースコードを読んでください。私が作ろうとしているのは、それがうまく動作しないかもしれないということです。 –

+1

ほとんどのjvm実装は割り込み可能なIO操作をサポートしていません。私はおそらく太陽solaris jvmが一点でそれをサポートしたと思う。 – jtahlborn

12

私はこの質問は古いです知っているが、誰もが「現代のプラットフォーム」上Thread.interrupt()の「謎」を解決しているように思わないように私はいくつかの研究をしました。

これはWindows7(64ビット版)のJava 8でテストされています(ただし、他のプラットフォームでも同様です)。

Thread.interrupt()を呼び出すと、ないは何が起こることはInputStream.read()方法は-1で返し、Thread.interrupted() -flagが設定されていることであるInterruptedIOException 投げるん。

だから、次はInterruptedIOExceptionを投げ)「修正」(読み込みと考えられる:

static final int read(Socket socket, byte[] inData) 
    throws SocketTimeoutException, // if setSoTimeout() was set and read timed out 
      InterruptedIOException, // if thread interrupted 
      IOException    // other erors 
{ 
    InputStream in = socket.getInputStream(); 

    int readBytes = in.read(inData, 0, inData.length); 

    if (Thread.interrupted()) 
    { 
     throw new InterruptedIOException("Thread interrupted during socket read"); 
    } 

    return readBytes; 
} 
+1

入力/出力ストリーム操作中にJavaの動作が中断された場合、多くの人が期待するものではないので、 –

関連する問題