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.

One thought on “Using a queue to wait for a job to complete”

  1. We are using the JDK’s Callable and FutureTask classes for this purpose in our code:

    http://download.oracle.com/javase/6/docs/api/java/util/concurrent/FutureTask.html

    Put your content generation code in an implementation of Callable. Then instantiate a new FutureTask object and call its run() method in a new Thread/Job.

    Now when you call FutureTask.get(), the call is blocking until the computation has produced a result or has lead to an exception (which is passed as an ExecutionException when calling .get()).

    Like

Comments are closed.