0

複数のクライアントを処理するために複数のスレッドを生成する単純なサーバーを作成しています。サーバーが終了したときに、さまざまなストリームとスレッドをすべてシャットダウンして閉じる適切な方法を考えていました。

サーバーにシャットダウンを指示するメソッドを実行するshutdownHookを追加しました。次に、サーバーは、開いたすべてのスレッドにシャットダウン呼び出しをブロードキャストします。これにより、各スレッドの「isClosed」ブール値がtrueに設定されます。

私が期待しているのは、各スレッドがrun()メソッドの最後に到達して再びループすると、while(!isClosed)条件にヒットし、それによってすべての適切なソケット/ストリームを閉じて戻ることにより、適切に終了することです。

ただし、shutdownhookが完了した後にプログラムが終了する必要があるため、これですべてが適切に閉じられるかどうかはわかりません。終了メッセージを伝播するだけなので、かなり早く完了します。これは、一部のスレッドが適切に閉じるのに十分な時間がないことを意味しますか?

もしそうなら、戻る前に、shutdownhookですべてのスレッドを手動で閉じて、スレッドが閉じていることを確認するのが最善の方法でしょうか?

4

4 に答える 4

0

を使用することExecutorServiceはそれを行うための現代的な方法です。それはコードから非常に厄介なビットを奪います。

ここから始めるのが良いでしょう。

于 2013-02-14T00:00:35.690 に答える
0

サーバーが終了した場合、スレッドが適切に終了するのに十分な時間がない可能性が高いことは正しいです。ただし、何をしようとしているかによって、これが問題になる場合と問題にならない場合があります。クリーンアップ作業が必要ない場合は、スレッドが突然終了しても問題が発生しないため、おそらく心配する必要はありません。

ただし、実行する必要のあるクリーンアップ作業(データベースへの書き込みなど)がある場合は、別の作業が必要になります。これを(Javaで)行う最良の方法は、Executor / ExecutorServiceおよび関連アイテム(http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html)を使用することです。あなたの問題はこれらによってうまく対処されます、そしてあなたはスケーリングがはるかに簡単になるようにスレッドプール管理のようないくつかの素晴らしい景品を手に入れます。たとえば、クライアントごとに新しいスレッドを生成する場合、1分あたり100万のスレッドを作成できないため、後でスケーリングしようとすると大きな問題が発生します。

生のスレッドを使用することに慣れている場合、Excecutorのものを使用することは少し調整ですが、調査する価値があります。幸運を!

于 2013-02-14T00:04:07.653 に答える
0

shutdownHookは、サイクルの後半で発生するため、そのように使用することはできません。すぐに完了することが期待されており、JVMはすでにダウンしているため、デーモンの場合は既存のスレッドを使用する可能性があります。

接続スレッドに読み取りタイムアウトを15〜30秒に設定します。タイムアウトが発生した場合は(SocketTimeoutException)、ソケットを閉じてスレッドを終了します。もちろん、クライアントは接続の切断に対処する必要がありますが、すでにそれを行う必要があります。次に、シャットダウンする場合は、新しい接続の受け入れを停止します(たとえば、を閉じServerSocketて、受け入れスレッドが結果の例外に正しく対処するようにします)。既存の接続スレッドがすべて終了すると、JVMは終了します。実際には、タイムアウト期間に最長のトランザクションの長さを加えた時間より長くかかることはありません。接続スレッドがデーモンではないことを確認してください。

トランザクションの途中でクライアントが切り落とされることを気にしない場合は、電話してくださいSystem.exit().

于 2013-02-14T04:33:39.923 に答える
0

スレッドをデーモンスレッドにすることを検討しましたか。t.setdaemon(true);を追加するだけです。スレッドのstartメソッドを呼び出す前。プログラムの終了時にこれらのスレッドを終了する必要がある場合は、デーモンにするよりも、他のすべての非デーモンスレッドが終了するとスレッドを強制終了します。スレッドプールで使用されるスレッドは、デーモンである必要があるスレッドの良い例です。そして、私はそれがあなたにとって役立つことができると本当に思います。

于 2013-02-14T12:29:32.820 に答える