|  As mentioned in Chapter 
              8, J2SE5.0 adds numerous enhancements to the threading control 
              and concurrency features of Java. Some of the enhancements are advanced 
              features beyond the scope of this book, but we explain some of the 
              simpler new features here. The Executor Class
  The most important new feature for the casual developer 
              of multithreaded applications is the new Executor 
              framework. A java.util.concurrent.Executor 
              is an object that executes Runnable 
              tasks. It is similar to calling  
               new Thread 
                (aRunnableObject).start (); For a single new thread, there is perhaps not much 
              reason to use an Executor. 
              However, most multithreaded applications involve several threads. 
              Threads need stack and heap space, and, depending on the platform, 
              thread creation can be expensive. In addition, cancellation and 
              shutdown of threads can be difficult, as seen in Chapter 
              8, and a well-designed and implemented thread 
              pooling scheme is not simple.  The new Executor 
              framework solves all those problems in a way that decouples 
              task submission from the mechanics of how each task will be run, 
              including the details of thread use, scheduling, etc.  An Executor 
              can and should be used instead of explicitly creating threads. For 
              example, rather than creating a new thread and starting it as above, 
              you can use:  
               Executor executor 
                = some Executor factory method;exector.execute (aRunnable);
 Notice that our Executor 
              object was returned by an Executor 
              factory. (We discuss design patterns like factory methods in Chapter 
              16; a factory is a standard name for a method that is 
              used to obtain an instance of a class or subclass rather than making 
              it with a constructor.)  There are several static Executor 
              factory methods available in the java.util.concurrent.Executors 
              class. If you have several Runnable 
              tasks to carry out, but do not have specific requirements about 
              the order in which they occur, then a simple thread pool arrangement 
              is provided as follows:  
               Executor executor 
                = Executors.newFixedThreadPool (5);executor.execute (new RunnableTask1 ());
 executor.execute (new RunnableTask2 ());
 executor.execute (new RunnableTask3 ());
 ...
  Here the tasks run and complete under the control 
              of the Executor, 
              which reuses threads from the thead pool as needed without incurring 
              the overhead of always creating new threads.  The newFixedThreadPool 
              () method actually returns an object of type ExecuterService, 
              which is a subinterface of Executer. The 
              ExecuterService includes a number of methods 
              for managing a thread pool. For example, the above pool could be 
              stopped with 
              ((ExecuterService)executor).shutdown(); 
                 As explained in the specification, 
              this means that no further tasks can be submitted and currently 
              running threads will continue until they finish. The shutdownNow() 
              method will make "best-effort attempts to stop processing 
              actively executing tasks", but there is no guarantee that a 
              thread will be stopped (e.g. if it is in an endless loop in the 
              run() method.) See Chapter 
              8: Java: Stopping Threads for advice on properly killing a thread. There are several more Executor 
              factories in the Executors 
              class for other needs beyond the scope of this book. Refer to the 
              J2SE 5.0 API docs for complete information.  The Callable 
              Interface  The new java.util.concurrent.Callable 
              interface is much like Runnable 
              but overcomes two drawbacks with Runnable. 
              The run() 
              method in Runnable 
              cannot return a result (i.e. it returns void) 
              and cannot throw a checked exception. If you try to throw an exception 
              in a run() 
              method, the javac 
              compiler insists that you use a throws clause in the method signature. 
              However, the superclass run() 
              method doesn't throw an exception, so javac 
              will not accept this.  If you need a result from a Runnable 
              task, you have to provide some external means of getting that result. 
              A common technique is to set an instance variable in the Runnable 
              object and provide a method to retrieve that value. For example,  
               public MyRunnable 
                implements Runnable{
 private int fResult = 0;
 public void run () {
 ...
 fResult = 1;
 } // run
 
 // A getter method to provide the result of the thread.
 public int getResult () { return fResult; }
 
 } // class MyRunnable
 
  The Callable 
              interface solves these problems. Instead of a run() 
              method the Callable 
              interface defines a single call() 
              method that takes no parameters but is allowed to throw an exception. 
              A simple example is  
              import java.util.concurrent.*;public class MyCallable implements Callable
 {
 public Integer call () throws java.io.IOException 
                {
 return 1;
 }
 } // MyCallable
  This call() 
              method returns an Integer. 
              (Note that we have conveniently used the autoboxing 
              support in J2SE 5.0 to have the literal int 
              1 value automatically boxed into an Integer 
              return value.)  Getting the return value from a Callable 
              depends upon the new generics feature:  
               FutureTask 
                task = new FutureTask (new MyCallable ());ExecutorService es = Executors.newSingleThreadExecutor ();
 es.submit (task);
 try {
 int result = task.get ();
 System.out.println ("Result from task.get () = " + 
                result);
 }
 catch (Exception e) {
 System.err.println (e);
 }
 es.shutdown ();
  Here, we use the FutureTask 
              class that supports an Integer 
              return value. Then the task is submitted using the ExecutorService 
              submit() method, and the result is obtained from the FutureTask 
              get() method, again using auto-unboxing to convert the Integer 
              to an int. See the API documentation for more information on ExecutorService, 
              and FutureTask.
 Other Concurrency 
              Enhancements  We discuss some other new concurrency tools in Chapter 
              8: Supplements: More About Concurrency. Other enhancements in 
              the java.util.concurrency package not discussed here include advanced 
              atomic types, new high-performance thread-safe collections ConcurrentHashMap, 
               CopyOnWriteArrayList, 
              and CopyOnWriteArraySet. 
              See the API documentation for more information on these new collections 
              and other features. 
 References & Web Resources   Latest update: Apr.30, 2006  |