Welcome Guest!
Create Account | Login
Locator+ Code:

Search:
FTPOnline
Channels Conferences Resources Hot Topics Partner Sites Magazines About FTP RSS 2.0 Feed

Free Subscription to Java Pro

Put JDK 1.5's Executor to Work for You (Continued)

(As recommended previously, avoid this technique, as it increases the risk of application failure or performance problems.) Here's the same code, but it uses a thread pool:

class WebServer {
  public static void main(
    String[] args) {
    ExecutorService pool =
      Executors.
      newFixedThreadPool(7);
    ServerSocket socket = 
      new ServerSocket(80);
    while (!shutdownRequested) {
      final Socket connection = 
        socket.accept(); 
      Runnable r = 
        new Runnable() {
        public void run() {
          handleRequest(
            connection);
        }
      };
      pool.execute(r);
    }
    // Complete outstanding 
    // requests before exiting
    executor.shutdown();
    executor.awaitTermination();
  }
}
ADVERTISEMENT

As you can see, retrofitting existing code to use Executor is quite easy. Two other elements of the Executor framework are the Future interface and the Callable interface. The Future interface represents a handle to a task, whether that task is queued currently for execution, is in the process of execution, or it has finished executing, and is useful when one or more threads need to wait (or poll) synchronously for a result to become available. Callable is the result-bearing equivalent of Runnable, and the FutureTask class is an adapter that turns a Callable into a Future.

Here's an approach to implementing a cache using Executor and Future, as well as some other new classes from java.util.concurrent, such as ConcurrentHashMap:

public class CachedFunction {
  private ConcurrentMap> map =
    new ConcurrentHashMap>();
  private Executor executor =
    Executors.
    newFixedThreadPool(8);

  public V get(final K key) {
    Future f = map.get(key);
    if (f == null) {
      Callable c = 
        new Callable() {
        public V call() {
        // return value 
        // associated with key
        }
      };
      f = new FutureTask(c);
      Future old = 
        map.putIfAbsent(key, f);
        if (old == null) 
          executor.execute(f);
        else
          f = old;
    }
    return f.get();
  }
}

The Executor framework is a powerful, scalable, extensible framework for executing and managing asynchronous tasks. With a host of execution policies and options, there is no need for the vast majority of applications to perform their own thread management. One of the Executor implementations in the JDK will almost certainly do the job, and likely do it better.

About the Author
Brian Goetz is a principal consultant at Quiotix, a software development and consulting firm located in Los Altos, California, and he has been a professional software developer for the past 17 years. He serves on several JCP Expert Groups, including JSR 166. See Brian's published and upcoming articles in popular industry publications at www.quiotix.com/~brian/pubs.html. Contact Brian at .




Back to top













Java Pro | Visual Studio Magazine | Windows Server System Magazine
.NET Magazine | Enterprise Architect | XML & Web Services Magazine
VSLive! | Thunder Lizard Events | Discussions | Newsletters | FTP Home