Thread Management

Assume thread t1 holds resource R. Assume t1 is suspended:

t1.suspend();

Now no thread may access R until t1 is resumed. If thread t2 attempts to lock R before calling t1.resume(), then deadlock occurs.

Suppose t1 is in the middle of modifying R when t2 stops it:

t1.stop();

Since t1 didn't complete the modification of R, R may now be in an inconsistent state.

For these reasons the suspend, stop, and resume methods are now deprecated.

The following example provides a customizable framework that provides an extensible worker thread class and an extensible thread manager class.

Worker Threads

The WorkerThread class provides safe versions of stop, suspend, and resume called halt, pause, and unpause:

public class WorkerThread extends Thread {
   private boolean stop = false;
   private boolean pause = false;
   private static int nextID = 0; // id generator
   protected int id;
   public boolean DEBUG = true;
   public WorkerThread(String name, int id) {
      super(name);
      this.id = id;
   }
   public WorkerThread(int id) {
      this("Worker thread " + id, id);
   }
   public WorkerThread(String name) {
      this(name, nextID++);
   }
   public WorkerThread() {
      this(nextID++);
   }

   synchronized public void halt() { stop = true; }
   synchronized public void pause() { pause = true; }
   synchronized public void unpause() { notifyAll(); }
   // override this in a subclass:
   protected boolean task() {
      if (DEBUG)
         System.out.println(getName() + " is performing its task");
      return true; // call me again
   }

   public void run() {
      while(true) {
         synchronized(this) {
            if (stop) break;
            if (pause) {
               pause = false;
               if (DEBUG)
                  System.out.println(getName() + " is pausing");
               try {
                  wait();
                  if (DEBUG)
                     System.out.println(getName() + " is resuming");
               } catch(InterruptedException ie) {
                  System.err.println(ie.getMessage());
               }
            }
         }
         if (!task()) break;
         try {
            sleep(100); // be cooperative
         } catch(InterruptedException ie) {
            System.err.println(ie.getMessage());
         }
      } // while
      if (DEBUG) System.out.println(getName() + " is shutting down");
   }
}

The Thread Manager

The thread manager manages a pool of worker threads:

public class ThreadManager {

   private List workers = new ArrayList();
   public void clear() { workers.clear(); }
   public void add(WorkerThread worker) { workers.add(worker); }
   public void pauseAll() {
      Iterator p = workers.iterator();
      while(p.hasNext()) {
         WorkerThread worker = (WorkerThread)p.next();
         worker.pause();
      }
   }
   public void unpauseAll() {
      Iterator p = workers.iterator();
      while(p.hasNext()) {
         WorkerThread worker = (WorkerThread)p.next();
         worker.unpause();
      }
   }
   public void haltAll() {
      Iterator p = workers.iterator();
      while(p.hasNext()) {
         WorkerThread worker = (WorkerThread)p.next();
         worker.halt();
      }
   }
   public void startAll() {
      Iterator p = workers.iterator();
      while(p.hasNext()) {
         WorkerThread worker = (WorkerThread)p.next();
         worker.start();
      }
   }
   public String toString() { return workers.toString(); }


   public void joinAll() { joinAll(0); }
   public void joinAll(long msecs) {
      Iterator p = workers.iterator();
      while(p.hasNext()) {
         WorkerThread worker = (WorkerThread)p.next();
         try {
            if (worker.isAlive()) worker.join(msecs);
            if (worker.isAlive()) worker.halt();
         } catch(InterruptedException ie) {
               System.err.println(ie.getMessage());
               if (worker.isAlive()) worker.destroy();
         } finally {
            System.out.println(worker.getName() + " has died");
         }
      }
      System.out.println("The manager will now die ... ");
   }
   public void delay(int ms) {
      try {
         Thread.sleep(ms);
      } catch(InterruptedException ie) {
         System.err.println(ie.getMessage());
      }
   }
  

   // test
   public static void main(String[] args) {
      ThreadManager master = new ThreadManager();
      for(int i = 0; i < 5; i++) {
         master.add(new WorkerThread(i));
      }
      master.startAll();
      master.delay(500);
      master.pauseAll();
      master.delay(500);
      master.unpauseAll();
      master.joinAll(500);
      // master.haltAll();
   }
}

Program Output

Worker thread 2 is performing its task
Worker thread 3 is performing its task
Worker thread 4 is performing its task
Worker thread 2 is performing its task
Worker thread 3 is performing its task
Worker thread 4 is performing its task
Worker thread 2 is performing its task
Worker thread 3 is performing its task
Worker thread 4 is performing its task
Worker thread 2 is performing its task
Worker thread 3 is performing its task
Worker thread 4 is performing its task
Worker thread 2 is performing its task
Worker thread 3 is performing its task
Worker thread 4 is performing its task
Worker thread 2 has died
Worker thread 2 is shutting down
Worker thread 3 is performing its task
Worker thread 4 is performing its task
Worker thread 3 is performing its task
Worker thread 4 is performing its task
Worker thread 3 is performing its task
Worker thread 4 is performing its task
Worker thread 3 is performing its task
Worker thread 4 is performing its task
Worker thread 3 is performing its task
Worker thread 3 has died
Worker thread 4 is performing its task
Worker thread 3 is shutting down
Worker thread 4 is performing its task
Worker thread 4 is performing its task
Worker thread 4 is performing its task
Worker thread 4 is performing its task
Worker thread 4 has died
The manager will now die ...
Worker thread 4 is shutting down