Search code examples
javamultithreadingsocketstry-catchserversocket

Try-with-resources and ServerSockets


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:

  1. What is the scope of serverSocket? Is it usable in the caught exception block, or elsewhere in the surrounding block? If not, how can one reliably close the socket?
  2. How is the socket closed in this instance? I assume the only way that this sample can stop executing is to forcefully end the process, but what happens to the open socket after this point? Is the port in use no longer available for other applications (or even the same application)?
  3. What happens to the new KKMultiServerThread? Is this thread cleaned up by the garbage collector once the thread has completed its work?

Solution

    1. 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.

    2. 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.