我不确定关闭我的服务器(和ExecutorService)究竟是什么问题。 我启动ServerMain并按Enter键,它启动带有socket.close()的server.shutdown()方法,但它不会抛出SocketException。我不知道这是否与ExecutorService无法关闭相关。 这是代码:
public class ServerMain {
public static void main(String[] args) throws DirectoryServerException, IOException {
TCPDirectoryServer server = new TCPDirectoryServer();
ExecutorService serverExecutor = Executors.newSingleThreadExecutor();
try {
server.start(1337);
serverExecutor.execute(server);
System.out.println("Server started. Press enter to terminate.");
System.in.read();
server.shutdown();
System.out.println("Server is shut down...");
} finally {
serverExecutor.shutdown();
while (!serverExecutor.isTerminated()) {
try {
if (!serverExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
System.err.println("Problem with shutting down the Executor");
serverExecutor.shutdownNow();
}
} catch (InterruptedException ignore) {
}
}
}
}
}
这是服务器:
public class TCPDirectoryServer implements DirectoryServer {
private int port;
private ConcurrentHashMap<ParseDirectory, Histogram> cache;
private List<ClientHandler> clientHandlerList;
private ExecutorService clientExecutorService;
private Socket socket;
public TCPDirectoryServer() {
super();
this.cache = new ConcurrentHashMap<ParseDirectory, Histogram>();
this.clientHandlerList = new LinkedList<ClientHandler>();
this.clientExecutorService = Executors.newCachedThreadPool();
}
@Override
public void start(int port) throws DirectoryServerException {
this.port = port;
}
@Override
public void disconnect(ClientHandler clientHandler) {
clientHandlerList.remove(clientHandler);
}
@Override
public void shutdown() throws DirectoryServerException {
try {
socket.close();
} catch (IOException e) {
throw new DirectoryServerException(e);
}
}
@Override
public void run() {
try (ServerSocket serverSocket = new ServerSocket(port)) {
while (true) {
socket = serverSocket.accept();
clientHandlerList.add(connect(socket));
}
} catch (SocketException e) {
System.err.println("AAAA");
System.out.println("Server is shutting down");
} catch (IOException e) {
System.out.println("Something failed " + e.getMessage());
}
}
答案 0 :(得分:2)
这部分:
while (true) {
socket = serverSocket.accept();
clientHandlerList.add(connect(socket));
}
...当你调用shutdown
时,不会抛出SocketException,因为你正在那里关闭一个客户端套接字(最后连接的那个)。 ServerSocket仍处于打开状态,正在等待传入的请求。
答案 1 :(得分:0)
调用serverExecutor.shutdown()仍然会导致服务器在关闭之前等待所有进程完成。这是一个优雅的关闭。它可能正在等待“while(true)”循环退出,它看起来并不像以往那样。尝试调用serverExecutor.shutdownNow();终止你的程序。
答案 2 :(得分:0)
在你的TCPDirectoryServer类中,使serverSocket成为一个成员变量,你的shutdown方法应该如下所示
public void shutdown() {
......
this.serverSocket.close();
........
}
当关闭客户端套接字时,如果套接字为空(没有人连接到您的服务器),请注意NPE。这也会阻止您的服务器关闭。