edu.ucla.util
Class Interruptable

Object
  extended by Interruptable
All Implemented Interfaces:
Runnable

public abstract class Interruptable
extends Object
implements Runnable

A base class that helps you define a piece of code that might be invoked "too often", that is: a piece of code that performs an expensive task that must be restarted afresh whenever it is run at all. This type of task often arises from user-initiated GUI actions.

For example, you might design a complex, editable Swing component that listens for changes in an underlying data model. Changes to the model could be triggered by user-initiated edit actions on the Swing component, or by programmatic actions initiated elsewhere. The period between rapidly succeeding change events could be much shorter than the time it takes to refresh the component. Furhermore, you would prefer that the listening method return immediately rather than blocking until it finishes the refresh. In this case, we would prefer to abandon the redrawing task whenever a new change event occurs before we are finished. This class solves exactly this problem.

All the setup you have to do is extend this class and implement runImpl(Object). To use the class, instantiate one instance of it and call start() on that instance whenever you want to run the expensive code. Whever you call start(), this class will interrupt previous Threads spawned by calls to start(). However, it will be useful only if your implementation of runImpl(Object) calls Thread.sleep(n), n > 0, every so often.

This prototypical example class is a recommended use of Interruptable, and it illustrates the above example :

class ComplexEditableComponent extends JComponent
{
        void eventDispatched( Event event ){
                refresh( event.getHint() );
        }

        void refresh( Hint hint ){
                myRunRefresh.start( hint ) ;
        }

        class RunRefresh extends Interruptable {
                public void runImpl( Object arg ){
                        ComplexEditableComponent.this.refreshImpl( (Hint)arg );
                }
        }

        void refreshImpl( Hint hint ){
                try{
                        Thread.sleep(2);
                        expensiveA();
                        Thread.sleep(2);
                        expensiveB();
                        Thread.sleep(2);
                        expensiveC();
                }catch( InterruptedException e ){
                        cleanup();
                }
        }

        RunRefresh myRunRefresh = new RunRefresh();
}
        

Since:
121404
Author:
Keith Cascio

Nested Class Summary
static interface Interruptable.Veto
          Implement this interface to define a callback for deciding whether or not to go ahead with an interruption.
 
Field Summary
static boolean FLAG_DEBUG_OVERRIDE
           
static boolean FLAG_VERBOSE_OVERRIDE
           
static long LONG_PAUSE_GRACE_MILLIS
           
static String STR_NAME_PREFIX
           
static PrintStream STREAM_DEBUG
           
static PrintStream STREAM_VERBOSE
           
 
Constructor Summary
Interruptable()
           
 
Method Summary
 void cancel()
           
 boolean debug()
          Override this to return true to print debug messages.
 ThreadGroup getCurrentParent()
           
 String getName()
          For identification purposes
 String getNameMethodOfInterest()
          Override this to help print meaningful verbose messages.
 Object getSynch()
          We use a single, devoted Object to synchronize calls to runImpl(Object).
 void interrupt()
           
static int kill(ThreadGroup group)
           
static void printMethodStackTraceElement(Throwable throwable, String methodname, PrintStream stream, boolean abbreviate)
           
 void run()
          Run the task in the current Thread, ie bypass the normal functioning of this class.
 Thread run(boolean threaded)
          Run threaded or not.
 Thread run(boolean threaded, Object arg1)
          Run threaded or not.
 void run(Object arg1)
          Run the task in the current Thread, ie bypass the normal functioning of this class.
abstract  void runImpl(Object arg1)
          Implement this method to perform a expensive task.
 void setName(String name)
          Set a descriptive name to identify this task
 void setParent(ThreadGroup group)
           
 void setVeto(Interruptable.Veto veto)
          Set a callback.
 Thread start()
          Run the expensive task in a new Thread.
 Thread start(long millis)
          Run the expensive task in a new Thread that waits for the specified number of milliseconds before beginning the task.
 Thread start(long millis, Object arg1)
          Run the expensive task in a new Thread that waits for the specified number of milliseconds before beginning the task.
 Thread start(Object arg1)
          Run the expensive task in a new Thread.
 void stop()
           
 boolean verbose()
          Override this to return true to print debug messages.
 
Methods inherited from class Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

FLAG_DEBUG_OVERRIDE

public static boolean FLAG_DEBUG_OVERRIDE

FLAG_VERBOSE_OVERRIDE

public static boolean FLAG_VERBOSE_OVERRIDE

LONG_PAUSE_GRACE_MILLIS

public static final long LONG_PAUSE_GRACE_MILLIS
See Also:
Constant Field Values

STREAM_VERBOSE

public static final PrintStream STREAM_VERBOSE

STREAM_DEBUG

public static final PrintStream STREAM_DEBUG

STR_NAME_PREFIX

public static final String STR_NAME_PREFIX
See Also:
Constant Field Values
Constructor Detail

Interruptable

public Interruptable()
Method Detail

runImpl

public abstract void runImpl(Object arg1)
                      throws InterruptedException
Implement this method to perform a expensive task. Call #checkInterrupted() every so often to allow the thread to be interrupted.

Parameters:
arg1 - The argument allows your task to take arguments passed in by calls to start(Object)
Throws:
InterruptedException

debug

public boolean debug()
Override this to return true to print debug messages.

Returns:
false
Since:
011505

verbose

public boolean verbose()
Override this to return true to print debug messages.

Returns:
false
Since:
011505

getNameMethodOfInterest

public String getNameMethodOfInterest()
Override this to help print meaningful verbose messages.

Returns:
null
Since:
011505

run

public final void run()
Run the task in the current Thread, ie bypass the normal functioning of this class.

Specified by:
run in interface Runnable

setVeto

public void setVeto(Interruptable.Veto veto)
Set a callback.

Since:
20060328

setName

public void setName(String name)
Set a descriptive name to identify this task

Since:
20060328

getName

public String getName()
For identification purposes

Returns:
the name set by setName(), or a generic name if setName() was never called
Since:
20060328

getSynch

public Object getSynch()
We use a single, devoted Object to synchronize calls to runImpl(Object). This method returns it.

Returns:
The Object used to synchronize runImpl(Object)

run

public void run(Object arg1)
Run the task in the current Thread, ie bypass the normal functioning of this class.

Parameters:
arg1 - Passed on to runImpl(Object)

run

public Thread run(boolean threaded)
Run threaded or not.

Parameters:
threaded - If true, run the expensive task in a new Thread (i.e. call start()). If false, run the task in the current Thread (i.e. call run()).
Returns:
New Thread if true, Thread.currentThread() if false.

run

public Thread run(boolean threaded,
                  Object arg1)
Run threaded or not.

Parameters:
threaded - If true, run the expensive task in a new Thread (i.e. call start(Object)). If false, run the task in the current Thread (i.e. call run(Object)).
arg1 - Passed on to runImpl(Object)
Returns:
New Thread if true, Thread.currentThread() if false.

start

public Thread start()
Run the expensive task in a new Thread.


start

public Thread start(Object arg1)
Run the expensive task in a new Thread.

Parameters:
arg1 - Passed on to runImpl(Object)

start

public Thread start(long millis)
Run the expensive task in a new Thread that waits for the specified number of milliseconds before beginning the task.

Parameters:
millis - Milliseconds to sleep before calling runImpl(Object).

start

public Thread start(long millis,
                    Object arg1)
Run the expensive task in a new Thread that waits for the specified number of milliseconds before beginning the task.

Parameters:
millis - Milliseconds to sleep before calling runImpl(Object).
arg1 - Passed on to runImpl(Object)

interrupt

public void interrupt()
Since:
20050225

stop

public void stop()
Since:
20050812

cancel

public void cancel()
Since:
20050812

setParent

public void setParent(ThreadGroup group)
Since:
20060719

getCurrentParent

public ThreadGroup getCurrentParent()
Since:
20060719

printMethodStackTraceElement

public static void printMethodStackTraceElement(Throwable throwable,
                                                String methodname,
                                                PrintStream stream,
                                                boolean abbreviate)
Since:
011505

kill

public static int kill(ThreadGroup group)
Returns:
number of active threads
Since:
20060720


Copyright 2010 UCLA Automated Reasoning Group