繁体   English   中英

终止线程的正确方法

[英]Proper way to terminate thread

我正在尝试基于Sockets编写聊天应用程序,但是我有点困惑,如何实际停止服务器。

这是我的Server构造函数

    public Server(int port) {
        this.port = port;
        this.shutdown = false;
        this.clientComponentSet = new HashSet<>();
        LOGGER.info("Starting the server...\n");

        dbConnection = new DBConnection();
        dbConnection.establish();
        if(dbConnection.isConnected()) {
           LOGGER.info("Established connection with database\n");
        } else {
           LOGGER.warn("Can't establish connection with database\n");
        }

        machineString = new SimpleStringProperty();
        addressString = new SimpleStringProperty();
        portString = new SimpleStringProperty();
        status = new SimpleStringProperty();
        status.set("Offline");
    }

然后run方法

@Override
    public void run() {
        try {
            serverSocket = new ServerSocket(port);

            Platform.runLater(
                    () -> {
                        try {
                            machineString.set(serverSocket.getInetAddress().getLocalHost().getHostName());
                            addressString.set(serverSocket.getInetAddress().getLocalHost().getHostAddress());
                        } catch (UnknownHostException e) {
                            LOGGER.error(e.toString());
                        }
                        portString.set(String.valueOf(this.port));
                        status.set("Online");
                    }
            );

            LOGGER.info("Server started\n");

            while(!serverSocket.isClosed() && !shutdown) {
                Socket clientSocket = serverSocket.accept();
                ClientComponent clientComponent = new ClientComponent(this, clientSocket);
                clientComponentSet.add(clientComponent);
                clientComponent.start();
            }
        } catch (IOException e) {
            LOGGER.error("Failed to start the server\n" + e.toString() + "\n");
        }
    }

最后,应该停止/关闭服务器的方法

public void stopServer() {
        try {
            serverSocket.close();
            shutdown = true;
            LOGGER.info("Server stopped\n");
        } catch (IOException e) {
            LOGGER.error(e.toString());
        }
    }

虽然,它没有按我预期的那样工作。 我启动然后停止服务器,日志如下所示:

2018-03-17 12:48:01信息启动服务器...

2018-03-17 12:48:02 INFO与数据库建立连接

2018-03-17 12:48:03 INFO服务器启动

2018-03-17 12:48:04 INFO服务器已停止

2018-03-17 12:48:04错误无法启动服务器java.net.SocketException:套接字已关闭

现在尝试重新启动服务器,将抛出

线程“ JavaFX应用程序线程”中的异常java.lang.IllegalThreadStateException

那我到底该如何停止/关闭服务器?

我实际上忘记了我的ServerController

public class ServerController {
    final static Logger LOGGER = Logger.getLogger(ServerController.class);
    private ServerController(){
    }
    private static ServerController instance = null;

    public static ServerController getInstance() {
        if(instance == null) {
            instance = new ServerController();
        }
        return instance;
    }

    private Server server;

    public void start() {
        server = new Server(Integer.parseInt(Property.getByKey("SERVER_PORT")));
        server.start();
        if(!server.isAlive()) {
            LOGGER.info("Server closed\n");
        }
    }
}

您可以解决的至少一处令人困惑的问题是,即使调用closeServer()也会出现错误。

我建议;

  • 您使shutdown volatile
  • 你总是先设置
  • 您检查服务器是否已关闭,并且仅在未关闭时打印错误。
  • 不要假设异常意味着它没有开始。
  • 始终使用堆栈跟踪打印Exception以获取原因,除非您非常有信心不需要它。

要重新启动线程,您需要创建一个新线程,要在关闭端口后侦听端口,则需要创建一个新的ServerSocket。

顺便说一句,您不需要在日志末尾添加额外的新行。

您收到“服务器启动失败”消息,表示正在等待建立连接时关闭ServerSocket。 ServerSocket.accept方法将阻塞您的线程,直到接收到一些输入。 我相信解决此问题的最佳方法是在您希望终止服务器时向它发送一些“关闭”信号。 收到关闭信号/消息后,您可以安全地关闭ServerSocket并终止while循环。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM