Concurrent Programming in Java
© 1996-1999 Doug Lea  

 

 


4.1 Oneway Messages

Follow-ups

Shared ServerSockets

An approach to constructing web services that is only briefly alluded to in the book is to have a set of worker threads themselves all share access to a single ServerSocket, thereby eliminating the host as a relay point. For example:
  class WebServiceWithSharedServerSocket {
    
    public WebServiceWithSharedServerSocket(int nthreads) throws IOException {
      ServerSocket ss = new ServerSocket(...);
      for(i = 0; i < nthreads; ++i)
        (new Thread(new ConnectionHandler(ss))).start();
    }
  }

  class ConnectionHandler implements Runnable {
    private final ServerSocket serverSocket;

    public ConnectionHandler(ServerSocket ss) { serverSocket = ss;  }

    public void run() {
     while (!Thread.interrupted()) {
      try {
        Socket s = serverSocket.accept()
        // handle the request
      }
      catch (...) {
        // ...
      }
    }
  }
Because blocking accepts from the ServerSocket behave in the same way as taking a task from a blocking channel serving as a workqueue, there is no reason to create your own Channels relayed from the host unless the host must play a role in dispatching, monitoring, or otherwise managing threads or requests. This is almost always more efficient, although harder to control. For example, dealing with cancellation of the service can be more challenging.

In some cases, it is possible to accommodate some Host intervention and management by centralizing the accept point, and surrounding it with additional processing performed under synchronization. For example, you could include code to possibly expand the pool (further extensions can be added to dynamically shrink it as well):

  class WebServiceWithSharedAccept {
    private final ServerSocket serverSocket;
    private final int minthreads;
    private final int maxthreads;
    private int nthreads;

    
    public WebServiceWithSharedAccept(int mints, in maxt) throws IOException {
      minthreads = mint;
      maxthreads = maxt;
      nthreads = mint;
      serverSocket = new ServerSocket(...);
 
      for(i = 0; i < nthreads; ++i)
        (new Thread(new ConnectionHandler(this))).start();
    }

    synchronized Socket accept() throws IOException {
      Socket s = serverSocket.accept();

      // upon connection, possibly increase pool size 
      if (nthreads < maxthreads) {
        ++nthreads;
        (new Thread(new ConnectionHandler(this))).start();
      }

      return s;
    }
  }

  class ConnectionHandler implements Runnable {
    private WebServiceWithSharedAccept host;

    public ConnectionHandler(WebServiceWithSharedAccept h) {  host = h  }

    public void run() {
     while (!Thread.interrupted()) {
      try {
        Socket s = host.accept()
        // handle the request
      }
      catch (...) {
        // ...
      }
    }
  }

Readings and Resources

Most details about messages, formats, transports, etc., used in practice are specific to particular packages and systems, so the best sources are their accompanying manuals and documentation.

Discussions of message passing in distributed systems can be found in the sources listed in 1.2.5. Any of several packages and frameworks can be used to extend the techniques discussed here to apply in distributed contexts. For example, most of these designs (as well as most in 4.2 and elsewhere in this book) can be adapted for use in JavaSpaces. Conversely, many distributed message passing techniques can be scaled down to apply in concurrent, non-distributed settings. Design and implementation using JavaSpaces is discussed in:

For different approaches, see for example the Aleph, JMS, and Ninja packages. Many commercial distributed systems are based on CORBA and related frameworks, which also include some support for oneway message passing. See: Some systems-level oneway messaging strategies otherwise similar to those presented here are described in: An argument that single-queue, single-thread event frameworks are a better basis for application programming than thread-based frameworks may be found in:

A discussion of threads and futures in Swing, along with sample code, can be found in an article by Joe Bowbeer at the Swing Connection: The Last Word in Swing Threads

Acknowledgments

Thanks to Miles Sabin for comments and suggestions.


Doug Lea
Last modified: Tue Dec 28 12:51:44 EST 1999