java - Try-with-resources 和 ServerSockets

标签 java multithreading sockets try-catch serversocket

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

最佳答案

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

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

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

关于java - Try-with-resources 和 ServerSockets,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20131360/

相关文章:

java - Retrofit 2 中同步请求和异步请求哪个更好

sockets - 建立的连接被主机中的软件中止了

C/C++ Posix BSD 套接字 - HTTP 请求始终返回状态 400

java - 将 DataHandler 转换为 byte[]

c# - 处理数千个 UDP 数据包并使用 Threads 将它们保存在远程数据库中的最佳方法是什么?

java - 无签名数据和签名数据

multithreading - 等待线程仍会占用CPU时间吗?

python - 从原始套接字捕获数据包时出错

Java:Jackson 缩进添加了新的 map 标签

java - 使用 JFileChooser 在 JPanel 中加载图像