package jutil; /** * Base class for all threads that need to be * safely stopped, paused, and unpaused. */ public class WorkerThread extends Thread { /** * set to true to stop the thread. */ private boolean stop = false; /** * set to true to pause the thread */ private boolean pause = false; /** * An ID generator. */ private static int nextID = 0; /** * This threads id number. */ private int id; /** * Set to true to see diagnostics */ 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++); } public boolean isPaused() { return pause; } public boolean isStopped() { return stop; } /** * Safely halt this thread. */ synchronized public void halt() { stop = true; } /** * Safely pause this thread */ synchronized public void pause() { pause = true; } /** * Safely unpause this thread. */ synchronized public void unpause() { notifyAll(); } /** * Override this method with the basic thread task. * @return true if it wants to be called again, false otherwise */ protected boolean task() { if (DEBUG) System.out.println(getName() + " is performing its task"); return false; } /** * repeatedly calls the task method until the thread is stopped or the * task method returns false. */ public void run() { while(true) { synchronized(this) { if (stop) break; if (pause) { if (DEBUG) System.out.println(getName() + " is pausing"); try { wait(); if (DEBUG) System.out.println(getName() + " is resuming"); pause = false; } catch(InterruptedException ie) { System.err.println(ie.getMessage()); } } } if (!task()) { stop = true; break;} try { sleep(100); // be cooperative } catch(InterruptedException ie) { System.err.println(ie.getMessage()); } } // while if (DEBUG) System.out.println(getName() + " is shutting down"); } }