【问题标题】:Try-with-resources and ServerSocketsTry-with-resources 和 ServerSockets
【发布时间】:2013-11-21 20:37:21
【问题描述】:

我正在阅读http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html 上的 KnockKnock 服务器示例,发现了一些我有一些疑问的代码。

try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
    while (listening) {
        new KKMultiServerThread(serverSocket.accept()).start();
    }
} catch (IOException e) {
    System.err.println("Could not listen on port " + portNumber);
    System.exit(-1);
}

我的问题:

  1. serverSocket 的范围是什么?它可以在捕获的异常块中使用,还是在周围块的其他地方可用?如果没有,如何可靠地关闭套接字?
  2. 在这种情况下如何关闭套接字?我假设该示例可以停止执行的唯一方法是强制结束进程,但是在此之后打开的套接字会发生什么?正在使用的端口是否不再可用于其他应用程序(甚至同一个应用程序)?
  3. new KKMultiServerThread 会发生什么情况?线程完成工作后,垃圾收集器是否会清理该线程?

【问题讨论】:

  • 服务器套接字在其析构函数中自行关闭,线程也“停止”。
  • serverSocket 变量的范围在这里讨论:stackoverflow.com/questions/18691352/…
  • @JeroenBollen Java 中没有析构函数。
  • @EJP 很抱歉弄糊涂了

标签: java multithreading sockets try-catch serversocket


【解决方案1】:
  1. 您不需要关闭 ServerSocket,这就是 try(resource)/catch 习惯用法的发明目的。它确保最终资源被正确关闭和释放。有问题的资源是所谓的AutoCloseable

  2. 与 Java 中保留的所有内存一样,一旦不再使用,最终将由 GC 清理。然而,只有当此类线程的 run() 方法完成时,才会发生这种情况。此外,仅当所有剩余线程都是守护线程时,JVM 才会终止,因此如果这些 KKMultiServerThreads 是标准(非守护)线程,则即使在上述循环完成后,JVM 也可能会持续存在,直到至少所有线程都完成为止。

他们终止上述循环的正确方法是将listening 设置为false,然后在接受线程上调用interrupt()。在这种情况下,accept() 方法将返回并立即跳转到异常处理,然后 try (resource) / catch(更像是 try/catch/finally close() )将确保服务器正确关闭。这也将释放其他程序正在使用的端口。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 2020-12-02
    • 2014-12-18
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多