可终止的线程观察者

时间:2013-04-13 16:36:09

标签: java concurrency

有五种从属算法和一种主算法。在每个主算法的迭代中,这五个从属算法并行工作(它们都实现了Runnable接口),当其中一个完成时,它会通知其他人,以便它们也终止,并且在所有这些算法完成之后,主人算法开始后处理。通知过程基于观察者模式。每个从属算法都实现Terminatable接口,并且有一个指向包含可运行列表的TerminationObserver类的链接,并且有这样的方法:

 public synchronized void terminateAll() {
    for (Terminatable terminatable : terminatables) {
        if (!terminatable.isTerminated()) {
            terminatable.terminate();
        }
    }
 }

每个从属算法都是一组迭代,因此通过将terminated布尔变量设置为true来执行终止,这是停止迭代条件的一部分。以下是从算法类的概述:

public class SlaveAlgorithm {

   /**
    * Process the algorithm.
    */    
   public void run() {
       try {
           threadBarrier.await();

           while (!stopConditionMet()) {
               performIteration()
           }

           // whether it is terminated by other algorithm or
           // the stop conditions met
           if (!isTerminated()) {  
              terminate();
              terminateOthers();
           }

       } catch (Exception e) {
        throw new RuntimeException(new AlgException(e));
       }
   }

   /**
    * Tests whether the algorithms is terminated.
    */
   public boolean isTerminated() {
       return terminated;
   }

   /**
    * Terminates the algorithm execution and
    * causes other algorithms to terminate as well.
    */
   public void terminate() {
       terminated = true;
   }

   /**
    * Removes the current algorithm form the termination observer's list
    * and requests the termination of other algorithms, left in the termination    observer.
    */
   private void terminateOthers() {
       terminationObserver.remove(this); // eliminate the already terminated process from the list
       terminationObserver.terminateAll();
   }
}

一切正常,但似乎这不是“最佳实践”。可能有一些我看不到的pitfals,或者可能有其他一些着名的做法来做我需要的事情?

1 个答案:

答案 0 :(得分:1)

您应该将terminateOthers()决策权留给TerminationObserver而不是SlaveAlgorithm。你应该有这样的东西:

public class SlaveAlgorithm {
  public void run() {
    try {
      threadBarrier.await();

      while (!stopConditionMet() && !isTerminated()) {
        performIteration()
      }
      done();
    }
    catch ...
  }

  /**
   * If not terminated notify observer the processing is done.
   */
  private void done() {
    if (!isTerminated()) {  
      terminationObserver.notifyDone(this)
    }
  }

观察者应该这样做:

public class TerminationObserverImpl {
  private void notifyDone(SlaveAlgorithm slave) {
    remove(slave); // Remove it from the list.
    terminateAll(); // Go through the list and terminate each slave.
  }
  ...