View Javadoc

1   package net.sf.sapjcosupport;
2   
3   /**
4    * Utility class to execute a method call asynchronously.
5    * <p/>
6    * This asynchronous method invoker uses a 'pull' mechanism to await completion.
7    * The client code just calls {@link #start()} and
8    * continues doing what it needs to do. When it is ready to wait for completion of the async method,
9    * it calls {@link #waitForCompletion()}.
10   *
11   * @author Niki Driessen
12   * @since 1.0
13   */
14  public abstract class AsyncMethodCall extends Thread {
15      /**
16       * A semaphore to synchronize the start and end of the method call
17       */
18      private final Object semaphore = new Object();
19      private boolean done;
20  
21      /**
22       * Implementation code of the method call.
23       * <p/>
24       * This is the code that gets executed asynchronously, when {@link #start()}
25       * is called.
26       *
27       * @see #start()
28       */
29      protected abstract void executeMethod();
30  
31      /**
32       * This method is a subclassed {@link Thread#run()} method
33       * that handles executing the actual method.
34       *
35       * @see #executeMethod()
36       * @see Thread#start()
37       * @see Thread#stop()
38       * @see Thread#Thread(ThreadGroup,
39       *      Runnable, String)
40       * @see Runnable#run()
41       */
42      public void run() {
43          synchronized (semaphore) {
44              try {
45                  executeMethod();
46              } catch (Throwable t) {
47                  t.printStackTrace();
48              } finally {
49                  done = true;
50                  semaphore.notifyAll();
51              }
52          }
53      }
54  
55      /**
56       * Synchronization point for the asynchronous method.
57       * <p/>
58       * Call this method when you are ready to wait for the async method to
59       * complete its work. This method will block until {@link #executeMethod()} is finished
60       * (which can be the case when this method is called, and it will return immediately...)
61       */
62      public void waitForCompletion() {
63          synchronized (semaphore) {
64              while (!done) {
65                  try {
66                      semaphore.wait();
67                  } catch (Exception e) {
68                      throw new RuntimeException(e.getMessage());
69                  }
70              }
71              done = false;
72          }
73      }
74  
75  }