私は古典的なサーバーマルチクライアントプログラムを持っています。サーバーはServerSocketをリッスンし、受信ソケットごとに新しいRunnableクラスを作成し、ExecuteServiceで実行します。Java try-with-recourses stuck
Runnableクラスのrunメソッドでは、try-with-resourcesブロックを開きます。tryストリームでは、inputstreamから読み取り、クライアントからFINコマンドを受け取るまで出力ストリームに書き込みます。すべて正常に動作し、クライアントは正常に切断されます。実行はfinallyブロックに達し、テストのためにいくつかのものを出力しますが、tryブロックを終了しないので、runメソッドを終了しないで、どこかで実行されます。おそらくinputstreamのreadメソッドです。
興味があればコードを投稿できます。
最終的にすべてを強制終了してrunメソッドを終了するにはどうすればよいですか?
コード:
Server.java:
public static void main(String[] args) {
playersReady = new ArrayList<Integer>();
ServerSocket server = null;
try {
server = new ServerSocket(Consts.PORT);
ExecutorService service = Executors.newFixedThreadPool(characters.size());
while(playersReady.size()<characters.size()){
RequestHandler handler = new RequestHandler(server.accept());
service.execute(handler);
}
service.shutdownNow();
service.shutdown();
while(!service.isTerminated()){}
System.out.println("finished");
RequestHandler.java
public final class RequestHandler implements Runnable {
.....
public void run() {
//DataOutputStream output = null;
//DataInputStream input = null;
try (DataOutputStream output = new DataOutputStream(socket.getOutputStream());
DataInputStream input = new DataInputStream(socket.getInputStream())){
// socket.setSoTimeout(500);
handleReady(input.readUTF().split(" "), output);
while (/*!shutdown && !socket.isClosed() && */socket.isConnected()) {
System.out.println("check before read " + character.getId());
String request = input.readUTF();
System.out.println("check after read " + character.getId());
System.out.println("-----------------------------------" + request);
if (shutdown) {
socket.shutdownInput();
socket.getOutputStream().flush();
socket.shutdownOutput();
break;
}
String[] requestParser = request.split(" ");
if (requestParser[1].equals("DMG")) {
// handle damage request
handleDamage(requestParser, output);
} else if (requestParser[1].equals("BND")) {
// handle bandage request
handleBandage(requestParser, output);
} else if (requestParser[1].equals("FIN")) {
// handle finish request
handleFin();
if (!socket.isClosed())
socket.shutdownInput();
if (!socket.isClosed()) {
socket.getOutputStream().flush();
socket.shutdownOutput();
}
shutdown = true;
break;
} else {
break;
}
}
} catch (SocketTimeoutException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
e.printStackTrace();
shutdown = true;
break;
} catch (Throwable e) {
e.printStackTrace();
} finally {
try {
System.out.println("finished");
if (!socket.isClosed())
socket.shutdownInput();
if (!socket.isClosed()) {
socket.getOutputStream().flush();
socket.shutdownOutput();
socket.close();
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("Done run");
}
....
System.out.println("finished")
最終的には が印刷されていますが、実行方法の最後のSystem.out.println("Done run")
はありません!!
なぜですか?
これはrunメソッドでスタックされていますが、私はreadUTF呼び出しでは思いますが、すべてのリソースを閉じました!
プログラムのデバッグを試しましたか?あなたの「私はreadUTF呼び出しで考える」というのは少し曖昧です。 – f1sh
私は何も特別なことはしませんでしたが、runメソッドを渡してJavaのRunnableクラスに移動して停止しますが、スレッドは実行を継続します – faris