Java ExecutorService 无法在执行服务器时关闭

标签 java server executorservice

我不确定关闭我的服务器(和 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());
    }
}

最佳答案

这部分:

    while (true) {
        socket = serverSocket.accept();
        clientHandlerList.add(connect(socket));
    }

...当您调用 shutdown 时,不会抛出 SocketException,因为您正在关闭那里的客户端套接字(最后连接的套接字)。 ServerSocket 仍然打开并等待传入​​请求。

关于Java ExecutorService 无法在执行服务器时关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41570948/

相关文章:

java - 强制将 API 从 26.1 降级到 25.4

Java Hibernate Validator 需要一个或另一个

java - JAXB 解码错误 : Expected elements are <{ } Root>

尝试录制声音时出现 javax.sound.sampled.LineUnavailableException

java - 在 Eclipse Oxygen 2 中设置 Tomcat 服务器

java - 一个应用程序依赖于其他应用程序的结果,我们如何在Java中实现这一点?

java - Java中如何检查类型是unsigned int还是signed int?

php - 服务器为肯定存在于正确目录中的资源提供 410 错误

Android:如何使用IdlingResource等待后台任务(Espresso)

Java ExecutorService 用法