2013-11-21 18 views
1

我正在阅读KnockKnock服务器示例http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html,我发现了一些代码,我有几个问题。Try-with-resources and ServerSockets

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怎么办?一旦线程完成其工作,线程是否清理了该线程?
+0

服务器套接字在析构函数中关闭,线程也“停止”。 –

+0

'serverSocket'变量的范围在这里讨论:http://stackoverflow.com/questions/18691352/try-with-resources-scope-of-resource – FGreg

+2

@JeroenBollen Java中没有析构函数。 – EJP

回答

1
  1. 你并不需要关闭的ServerSocket,这是在try(资源)/捕获人们就发明了。它确保最终资源被正确关闭和释放。有问题的资源是所谓的AutoCloseable

  2. 与在Java中保留的所有内存一样,一旦GC不再被使用,它最终会被GC清除。然而这只能在这样的线程的run()方法完成时才会发生。此外,如果所有剩余线程都是守护进程线程,则JVM将终止,因此如果这些KKMultiServerThreads是标准(非守护进程)线程,那么甚至在完成上述循环之后,JVM可能仍然存在,直到至少所有线程都完成为止。

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