title: Java: Design Ideas for Stopping Callable Thread
body: <p>I am writing a program that does some batch processing.  The batch elements can be processed independently of each other and we want to minimize overall processing time.  So, instead of looping through each element in the batch one at a time, I am using an ExecutorService and submitting Callable objects to it:</p>
  
  <pre><code>    public void process(Batch batch)
      {
          ExecutorService execService = Executors.newCachedThreadPool();
          CopyOnWriteArrayList&lt;Future&lt;BatchElementStatus&gt;&gt; futures = new CopyOnWriteArrayList&lt;Future&lt;BatchElementStatus&gt;&gt;();
  
          for (BatchElement element : batch.getElement())
          {
              Future&lt;MtaMigrationStatus&gt; future = execService.submit(new ElementProcessor(batch.getID(),
                      element));
              futures.add(future);
          }
  
          boolean done = false;
  
          while (!done)
          {
              for (Future&lt;BatchElementStatus&gt; future : futures)
              {
                  try
                  {
                      if (future.isDone())
                      {
                          futures.remove(future);
                      }
                  }
                  catch (Exception e)
                  {
                      System.out.println(e.getMessage());
                  }
  
                  if (futures.size() == 0)
                  {
                      done = true;
                  }
              }
          }
      }
  </code></pre>
  
  <p>We want to be able to allow the batch processing to be cancelled. Because I'm not using a loop, I can't just check at the top each loop if a cancel flag has been set.  </p>
  
  <p>We are using a JMS topic to which both the BatchProcessor and ElementProcessor will be listening to inform them the batch has been cancelled.</p>
  
  <p>There are a number of steps in the ElementProcess call() after which some of them the processing can be safely stopped but there's a point of no return.  The class has this basic design:</p>
  
  <pre><code>public class ElementProcessor implements Callable, MessageListener
  {
      private cancelled = false;
  
      public void onMessage(Message msg)
      {
          // get message object
          cancelled = true;
      }
  
      public BatchElementStatus call()
      {
          String status = SUCCESS;
  
          if (!cancelled)
          {
              doSomehingOne();
          }
          else
          {
              doRollback();
              status = CANCELLED;
          }            
  
          if (!cancelled)
          {
              doSomehingTwo();
          }
          else
          {
              doRollback();
              status = CANCELLED;
          }            
  
          if (!cancelled)
          {
              doSomehingThree();
          }
          else
          {
              doRollback();
              status = CANCELLED;
          }            
  
          if (!cancelled)
          {
              doSomehingFour();
          }
          else
          {
              doRollback();
              status = CANCELLED;
          }
  
          // After this point, we cannot cancel or pause the processing
  
          doSomehingFive();
          doSomehingSix();
  
          return new BatchElementStatus("SUCCESS");
      }
  
  }
  </code></pre>
  
  <p>I'm wondering if there's a better way to check if the batch/element has been cancelled other than wrapping method calls/blocks of code in the call method in the <code>if(!cancelled)</code> statements.</p>
  
  <p>Any suggestions?</p>