I was reading through the KnockKnock server example at http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html and I found a bit of code I have a few questions about.
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);
}
My questions:
serverSocket
? Is it usable in the caught exception block, or elsewhere in the surrounding block? If not, how can one reliably close the socket?new KKMultiServerThread
? Is this thread cleaned up by the garbage collector once the thread has completed its work?You do not need to close the ServerSocket, this is what the try(resource)/catch idiom has been invented for. It ensures that at the end the resource is properly closed and released. The resource in question is a so called AutoCloseable.
As with all memory reserved in Java, it will eventually be cleaned up by the GC once it is no longer in use. This however can only happen if the run() method of such thread has completed. Furthermore the JVM will only terminate, if all remaining threads are daemon threads, so if those KKMultiServerThreads are standard (non-daemon) threads, the JVM might persist even after the loop above has finished, until at least all threads are done.
They correct way to terminate the loop above, is to set listening
to false and then call interrupt()
on the accepting thread. In this case the accept() method will return and immediately jump to the exception handling, then the try (resource) / catch (which is more like a try/catch/finally close() ) will ensure that the server is properly closed. This will as well free the port in use for other programs.