Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added NCE/CS for case where socket is not shared

...

This method interrupts the current thread, however, it only stops the thread because the thread logic polls the interrupted flag using the method Thread.interrupted(), and shuts down when it is interrupted.

Noncompliant Code Example (Socket per thread)

This noncompliant code example shows a variant of the SocketReader class that creates a Socket per thread, that is, the socket is not shared amongst multiple threads. This is a common scenario in server applications that must accept connections and requests and dispatch them to different handling threads.

Code Block
bgColor#FFcccc

public class SocketReader implements Runnable {
  public void run() {
    Socket socket = null;
    try {
      socket = new Socket("somehost", 25);
    } catch (UnknownHostException e) {
      // Forward to handler	
    } catch (IOException e) {
      // Forward to handler
    }
    // Do some useful work
  }
}

This design does not permit a client to close the socket when a thread is blocked, or is performing some time consuming activity.

Compliant Solution (ThreadLocal)

This compliant solution uses a ThreadLocal wrapper around the socket so that a thread that calls initialValue() obtains a unique socket instance. The advantage of this approach is that a shutdownSocket() method can be provided so that clients external to the class can also shutdown the socket when it is blocked, or is performing some time consuming activity.

Code Block
bgColor#ccccff

class SocketReader implements Runnable {
  private static ThreadLocal<Socket> connectionHolder = new ThreadLocal<Socket>() {
    Socket socket = null;
    @Override public Socket initialValue() {		
      try {
        socket = new Socket("somehost", 25);
      } catch (UnknownHostException e) {
        // Forward to handler	
      } catch (IOException e) {
        // Forward to handler
      }
      return socket;
    }
	
    @Override public void set(Socket sock) {
      if(sock == null) { // Shuts down socket when null value is passed 	
        try {
  	  socket.close();
        } catch (IOException e) {
 	  // Forward to handler	
        }
      } else {
        socket = sock;
      }
    }
  };

  public static Socket getSocketConnection() {
    return connectionHolder.get();
  }

  public static void shutdownSocket() { // Allows client to close socket anytime
    connectionHolder.set(null);
  }

  public void run() {
    Socket socket = getSocketConnection();
    // Do some useful work
  }
}

Risk Assessment

Trying to force thread shutdown can result in inconsistent object state and corrupt the object. Critical resources may also leak if cleanup operations are not carried out as required.

...