<< 18 May 2011 | Home | 20 May 2011 >>

Using a queue to wait for a job to complete

A question I get often is how to perform an operation synchronously (that is blocking) instead of asynchronously when developing plugins. The question stems from the fact that most operations are done using the Job-framework where code is run in a background thread. But what if you need the result before continuing. What if you don't want to wait or the code doesn't lend itself to that approach?

I find that the easiest way (without resorting to Job scheduling rules) is to use the java.util.concurrent classes to make the calling thread wait for the Job to complete. This approach works for all job-types including Notes based operations using NotesSessionJob.

Code could look like this:

import java.util.concurrent.ArrayBlockingQueue;

public FeedLoader() {
   // define queue to hold a maximum of 1 element
   final ArrayBlockingQueue<Object> queue = 
      new ArrayBlockingQueue<Object>(1);
   
   // create and schedule job
   new NotesSessionJob("Getting Notes username") {
      @Override
      protected IStatus runInNotesThread(Session session, 
       IProgressMonitor monitor) 
       throws NotesException {
         // perform operation and store result
         FeedLoader.this.username = session.getUserName();

         // put stuff in the queue to signal we're done (we 
         // could also have used the queue to return the value)
         queue.offer(new Object());

         // return
         return Status.OK_STATUS;
      }
   }.schedule();
   
   // wait for job to complete (Queue.take() wont return until 
   // the job puts something in the queue)
   try {
      queue.take();
   } catch (Throwable t) {}
}

I'm sure there are other, and probably easier and better, ways to do it but this is how I often do it.

Tags :