关机钩未终止主线程

我正在尝试使用ctrl-c键盘快捷键关闭服务器,并且我搜索了执行此操作的方法并找到了这篇文章。


我尝试了此解决方案,但是当关闭关闭挂钩后,我的主线程也结束了而没有完成服务器关闭任务,并且该过程以代码1完成。


这是我的代码:


package test;


import java.io.IOException;

import java.net.ServerSocket;


public class Main implements Runnable {

    private ServerSocket serverSocket;


    private Main() {

        try {

            serverSocket = new ServerSocket(5000);

        } catch (IOException e) {

            e.printStackTrace();

            System.exit(10);

        }


        System.err.println("Waiting ctrl-c ...");


        Runtime.getRuntime().addShutdownHook(new Thread(this));


        try {

            while (serverSocket.accept() != null) {

                doSomething();

            }

            System.err.println("end while");

        } catch (IOException e) {

            System.err.println("end exception");

        } finally {

            System.err.println("trying to close the server...");

            try {

                // simulate a long job

                Thread.sleep(5000);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            // this line was never reached

            System.err.println("server closed");

        }


    }


    public static void main(String[] args) {

        new Main();

    }


    private void doSomething() {}


    @Override

    public void run() {

        System.err.println("ctrl-c pressed");

        try {

            System.err.println("trying to close socket");

            serverSocket.close();

            System.err.println("socket closed!!!");

        } catch (IOException e) {

            System.err.println("failed to close socket");

        }

    }

}

这是IntelliJ IDE内部的输出:


Waiting ctrl-c ...

ctrl-c pressed

trying to close socket

socket closed!!!

end exception

trying to close the server...


Process finished with exit code 1

我如何优雅地解决此问题?


蝴蝶不菲
浏览 147回答 2
2回答

冉冉说

当关闭挂钩完成后,我的主线程也结束了而没有完成服务器关闭任务可能在关闭挂钩完成之前。这是正确的行为。主线程被JVM强制终止。这就是CTRL / C的效果。这也意味着您的关机钩子基本上是没有意义的。您可以将其完全删除,并且主线程仍将以相同的方式退出。“服务器关闭任务”应位于关闭钩子中。这就是它的目的。但是它们不应阻塞或长时间运行:请参阅Javadoc。NBServerSocket.accept()不返回null。不要编写毫无意义的测试。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java