java - 终止线程的正确方法

标签 java sockets networking javafx-8

我正在尝试编写基于套接字的聊天应用程序,但我有点困惑,如何真正停止我的服务器。

这是我的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 INFO Starting the server...

2018-03-17 12:48:02 INFO Established connection with database

2018-03-17 12:48:03 INFO Server started

2018-03-17 12:48:04 INFO Server stopped

2018-03-17 12:48:04 ERROR Failed to start the server java.net.SocketException: socket closed

现在尝试再次启动服务器,将会抛出

Exception in thread "JavaFX Application Thread" 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() ,您的错误也会出现。

我建议;

  • 关闭 volatile
  • 你总是先设置它
  • 检查服务器是否关闭,如果没有关闭则仅打印错误。
  • 不要认为异常意味着它没有启动。
  • 始终打印带有堆栈跟踪的异常以获取原因,除非您非常确信不需要它。

要重启一个线程,需要创建一个新的线程,要监听一个端口关闭后的端口,需要创建一个新的ServerSocket。

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

关于java - 终止线程的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49335706/

相关文章:

Java - 并发/阻塞队列单元测试策略

java - 使用 Java 在本地机器上获取 MAC 地址

c - 获取网关以用于 ANSI C 中的给定 ip

algorithm - 从输入和输出字节确定压缩算法

linux - 在对方接受请求之前防止写入套接字

python - 有没有办法在 python 脚本中执行 arp -a cmd 命令?

java - Java 中的嵌入式 Pig : java. io.IOException:无法运行程序 "cygpath"

java - Spring boot资源文件夹中访问xml的问题

java - 为什么我的计算树节的代码有效?

sockets - 使用TCL socket 时悬窗