com.lc.util
Class LoopingThread

java.lang.Object
  |
  +--java.lang.Thread
        |
        +--com.lc.util.LoopingThread
All Implemented Interfaces:
java.lang.Runnable

public class LoopingThread
extends java.lang.Thread

Enhanced Thread allowing the runnable part to be called repeatingly (without creating a new java.lang.Thread instance each time. Also manages Throwables which may be thrown by the runnable part (referred as Executable Part in this class documentation).

Construction :

  LoopingThread lt = new LoopingThread(
    new INoisyRunnable() {
      public void run() throws SomeException {
        // ...
      }
    }
  ) ;
or :
  LoopingThread lt = new LoopingThread(
    new Runnable() {
      public void run() {
        // ...
      }
    }
  ) ;
or :
  LoopingThread lt = new LoopingThread() {
      public void doRun() throws SomeException {
        // ...
      }
    }
  ) ;

A LoopingThread's Executable Part can sleep in quiet way :

  INoisyRunnable nr = new INoisyRunnable() {
      public void run() throws InterruptedException {
        // ...
        Thread.sleep( 1000 ) ;
      }
    }

Setting a Throwable Handler :

  lt.setThrowableHandler( new IThrowableHandler() {
    public boolean handleThrowable( Throwable th ) {
      th.printStackTrace() ;
      return true ; // means it was handled
    }
  } ) ;

Controlling execution :

  lt.freezeLoop() ;
  // ...
  lt.unfreezeLoop() ;
  // ...
  lt.kill() ;

Note about Executable Part implementation
The Executable Part may use Thread.isInterrupted() method without restriction, since it does not modify the interrupted status of the thread. Thread.interrupted() method should be used carefully (or, better, avoided) since it will interfer with standard behavior of the LoopingThread.

Version:
$Revision: 1.2 $ $Date: 2002/03/16 01:37:09 $
Author:
Laurent Caillette
See Also:
IThrowableHandler

Fields inherited from class java.lang.Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
 
Constructor Summary
LoopingThread()
          Creates an instance of a LoopingThread.
LoopingThread(INoisyRunnable noisyRunnable)
          Creates an instance of a LoopingThread with a INoisyRunnable instance, which will make the Executable Part of the Thread.
LoopingThread(java.lang.Runnable runnable)
          Creates an instance of a LoopingThread with a Runnable instance, which will make the Executable Part of the Thread.
 
Method Summary
 void askForTermination()
          Terminates the main loop as soon as the Executable Parts finishes its current execution.
 void doRun()
          Override this method if you prefer to subclass LoopingThread instead of creating it with a INoisyRunnable or a Runnable.
 void freezeLoop()
          Freezes the main loop of the LoopingThread.
 void freezeSoon()
           
 java.lang.Runnable getTerminationHandler()
           
 IThrowableHandler getThrowableHandler()
           
 void interrupt()
          Redefines the default behavior by calling freezeLoop().
 boolean isAbortingOnThrowableThrown()
           
 boolean isFrozen()
           
 boolean isTerminating()
           
 void run()
          Starts a loop calling repeatingly the Executable Part.
 void setAbortingOnThrowableThrown(boolean aborting)
          Defines if the thread should die when the Executable throws a Throwable (except an InterruptedException).
 void setTerminationHandler(java.lang.Runnable handler)
          Sets the Termination Handler, which will be called when the LoopingThread terminates cleanly.
 void setThrowableHandler(IThrowableHandler throwableHandler)
          Sets a Throwable Handler which will be called for all Throwable caught from the Executable Part.
 void start()
          Redefines the default behavior.
 boolean unfreezeLoop()
          Wakes the main loop up.
 
Methods inherited from class java.lang.Thread
activeCount, checkAccess, countStackFrames, currentThread, destroy, dumpStack, enumerate, getContextClassLoader, getName, getPriority, getThreadGroup, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setName, setPriority, sleep, sleep, stop, stop, suspend, toString, yield
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

LoopingThread

public LoopingThread()
Creates an instance of a LoopingThread. This constructor only makes sense if doRun() method is overriden.

LoopingThread

public LoopingThread(INoisyRunnable noisyRunnable)
Creates an instance of a LoopingThread with a INoisyRunnable instance, which will make the Executable Part of the Thread.
Parameters:
noisyRunnable - The Executable Part of the Thread.
Throws:
NullPointerException - if noisyRunnable was null.

LoopingThread

public LoopingThread(java.lang.Runnable runnable)
Creates an instance of a LoopingThread with a Runnable instance, which will make the Executable Part of the Thread.
Parameters:
noisyRunnable - The Executable Part of the Thread.
Throws:
NullPointerException - if runnable was null.
Method Detail

doRun

public void doRun()
           throws java.lang.Throwable
Override this method if you prefer to subclass LoopingThread instead of creating it with a INoisyRunnable or a Runnable. This method will never be called if the LoopingThread instance was created with either LoopingThread( INoisyRunnable ) or LoopingThread( Runnable ).

setThrowableHandler

public final void setThrowableHandler(IThrowableHandler throwableHandler)
Sets a Throwable Handler which will be called for all Throwable caught from the Executable Part. The IThrowableHandler#handleThrowable( IThrowable ) method execution will take place in the running LoopingThread.

getThrowableHandler

public final IThrowableHandler getThrowableHandler()
Returns:
The current Throwable Handler.

setTerminationHandler

public final void setTerminationHandler(java.lang.Runnable handler)
Sets the Termination Handler, which will be called when the LoopingThread terminates cleanly.

getTerminationHandler

public final java.lang.Runnable getTerminationHandler()

isAbortingOnThrowableThrown

public final boolean isAbortingOnThrowableThrown()
Returns:
true if thread should die when the Executable Part throws a Throwable.

setAbortingOnThrowableThrown

public final void setAbortingOnThrowableThrown(boolean aborting)
Defines if the thread should die when the Executable throws a Throwable (except an InterruptedException). Default is true.
Parameters:
aborting - true if thread should be terminated.

run

public final void run()
Starts a loop calling repeatingly the Executable Part.
Executable part means :

The loop will be performed until the freezeLoop() or #kill() are called, or until a Throwable thrown by Executable part breaks it (see below). Once the LoopingThread is frozen, its loop can be restarted by calling unfreezeLoop() method.

Throwable handling
If there was a Throwable Handler defined (by #setThrowableHandler()) then it is called if some Throwable is thrown by the Executable part (except if the Throwable was an InterruptedException). If none was defined (or if it returns false), the behavior depends of abortOnThrowable. If true (default), the Throwable will be wrapped in a CascadingRuntimeException and re-thrown. If false, the loop will continue after the Throwable printed its stack trace.
If the Throwable Handler throws a Throwable, its stack trace will be printed, and the loop will continue as defined above.

Overrides:
run in class java.lang.Thread
Throws:
CascadingRuntimeException - If
See Also:
IThrowableHandler, #setAbortingOnThrowableThrown()

freezeLoop

public final void freezeLoop()
Freezes the main loop of the LoopingThread. As it relies on the Thread.interrupt() method, it won't stop the Thread immediately, but wait for the Executable Part to finish its execution. Does nothing if the LoopingThread was not started yet, or already frozen / terminating.

freezeSoon

public final void freezeSoon()

unfreezeLoop

public final boolean unfreezeLoop()
Wakes the main loop up. Starts the LoopingThread if not already done.
Returns:
true If the operation was successful, false if not (e.g. when the LoopingThread was terminating).

isFrozen

public final boolean isFrozen()
Returns:
true if the LoopingThread has been frozen or asked for termination.

interrupt

public final void interrupt()
Redefines the default behavior by calling freezeLoop().
Overrides:
interrupt in class java.lang.Thread

start

public void start()
Redefines the default behavior.
Overrides:
start in class java.lang.Thread
Throws:
UnsupportedOperationException - When LoopingThread already started or terminating.

askForTermination

public final void askForTermination()
Terminates the main loop as soon as the Executable Parts finishes its current execution. The isTerminating() will return true as soon as this method was called.
See Also:
freezeLoop()

isTerminating

public final boolean isTerminating()
Returns:
true if the LoopingThread has been asked for termination.