【发布时间】:2021-12-21 10:10:49
【问题描述】:
我正在实现一个传输服务器程序,它从客户端(通过控制台输入)获取消息,然后将其转发到某种邮箱。
为了允许不同客户端同时接收多个消息,我首先创建了一个实现Runnable 接口的类。每个此类实例都将处理与一个客户端的通信:
public class ClientConnection implements Runnable {
//...
//...
@Override
public void run() {
try {
// prepare the input reader and output writer
BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);
Message message = new Message();
String request = "";
// read client requests
while ((request = reader.readLine()) != null) {
System.out.println("Client sent the following request: " + request);
String response;
if (request.trim().equals("quit")) {
writer.println("ok bye");
return;
}
response = message.parseRequest(request);
if (message.isCompleted()) {
messagesQueue.put(message);
message = new Message();
}
writer.println(response);
}
} catch (SocketException e) {
System.out.println("ClientConnection: SocketException while handling socket: " + e.getMessage());
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (InterruptedException e) {
System.out.println("Client Connection was interrupted!");
e.printStackTrace();
} finally {
if (clientSocket != null && !clientSocket.isClosed()) {
try {
clientSocket.close();
} catch (IOException ignored) {}
}
}
}
}
我确实有一个父线程负责启动和管理所有 ClientConnection 可运行对象:
@Override
public void run() {
clientConnectionExecutor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
while (true) {
Socket clientSocket;
try {
// wait for a Client to connect
clientSocket = serverSocket.accept();
ClientConnection clientConnection = new ClientConnection(clientSocket, messagesQueue);
clientConnectionExecutor.execute(clientConnection);
} catch (IOException e) {
// when this exception occurs, it means that we want to shut down everything
clientConnectionExecutor.shutdownNow(); // force terminate all ClientConnections
return;
}
}
}
现在根据this Stackoverflow Question,我预计一旦调用shutdownNow();,我的ClientConnection.run() 方法中就会抛出一个InterruptedException,在那里,它应该打印Client Connection was interrupted!。但这并没有发生,因此似乎永远无法到达 catch 子句,输入读取循环只是继续。
我在另一个 Stackoverflow 问题中读到,这可能与块中的其他一些代码行有关,似乎正在使用 InterruptedException,但没有任何关于代码行可以做到这一点的特定信息。所以我很感谢任何提示。
编辑:事实证明,只要我通过在客户端上键入“quit”手动退出循环,循环就会退出,然后,Client Connection was interrupted! 将被打印出来。所以不知何故,只要循环正在运行,异常似乎就会被忽略,并且只在之后处理。
【问题讨论】:
标签: java try-catch threadpoolexecutor java-threads interrupted-exception