Socket client does not terminate
<p>Why the client code does not terminate? (We need to start the server program first before running the client)</p>

<p>Server Code:</p>

<pre><code>    public class ServerSocketTest {

static final int PORT = 9999;

public static void main(String[] args) throws IOException {
    final ServerSocket serverSocket = new ServerSocket(PORT);

    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

    while (true) {
        final Socket socket = serverSocket.accept();
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                System.out.println(socket);
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }

   }

  }
</code></pre>

<p>Client code:</p>

<pre><code>   public class SocketClient {

public static void main(String[] args) throws UnknownHostException,
        IOException {
    final Socket socket = new Socket("localhost", ServerSocketTest.PORT);

    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            System.out.println("waiting to close socket " );
            printThread(Thread.currentThread());
            try {                   
                socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            System.out.println("waiting to exit");
            printThread(Thread.currentThread());                
            System.exit(0);
        }
    });
}

static void printThread(Thread currentThread) {
    System.out.println(currentThread + ": Alive=" + currentThread.isAlive()
            + ",Daemon=" + currentThread.isDaemon());
   }
 }
</code></pre>

<hr>

<p>I use Ubuntu. Using jconsole, I could trace the following threads plus some other RMI &amp; JMX threads:</p>

<hr>

<p>Name: Reference Handler
State: WAITING on java.lang.ref.Reference$Lock@14f38ff
Total blocked: 1  Total waited: 2</p>

<p>Stack trace: 
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:503)
java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)</p>

<hr>

<p>Name: Finalizer
State: WAITING on java.lang.ref.ReferenceQueue$Lock@3037a0
Total blocked: 1  Total waited: 2</p>

<p>Stack trace: 
java.lang.Object.wait(Native Method)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:177)</p>

<hr>

<p>Name: Signal Dispatcher
State: RUNNABLE
Total blocked: 0  Total waited: 0</p>

<p>Stack trace: </p>

<hr>

<p>Name: DestroyJavaVM
State: WAITING on net.SocketClient$2@39b27b
Total blocked: 0  Total waited: 1</p>

<p>Stack trace: 
java.lang.Object.wait(Native Method)
java.lang.Thread.join(Thread.java:1258)
java.lang.Thread.join(Thread.java:1332)
java.lang.ApplicationShutdownHooks.runHooks(ApplicationShutdownHooks.java:106)
java.lang.ApplicationShutdownHooks$1.run(ApplicationShutdownHooks.java:46)
java.lang.Shutdown.runHooks(Shutdown.java:123)
java.lang.Shutdown.sequence(Shutdown.java:167)
java.lang.Shutdown.shutdown(Shutdown.java:234)
   - locked java.lang.Class@127bd04</p>

<hr>

<p>Name: Thread-1 (This is the shutdown hook I added to invoke System.exit)
State: BLOCKED on java.lang.Class@127bd04 owned by: DestroyJavaVM
Total blocked: 1  Total waited: 0</p>

<p>Stack trace: 
java.lang.Shutdown.exit(Shutdown.java:212)
java.lang.Runtime.exit(Runtime.java:107)
java.lang.System.exit(System.java:960)
net.SocketClient$2.run(SocketClient.java:31)</p>

<hr>

<p>Name: SIGINT handler(This seems to be spwaned when Control+C is pressed)
State: BLOCKED on java.lang.Class@127bd04 owned by: DestroyJavaVM
Total blocked: 1  Total waited: 0</p>

<p>Stack trace: 
java.lang.Shutdown.exit(Shutdown.java:212)
java.lang.Terminator$1.handle(Terminator.java:52)
sun.misc.Signal$1.run(Signal.java:212)
java.lang.Thread.run(Thread.java:722)</p>
