org.norther.tammi.acorn.util.concurrent
Class TimerDaemon

java.lang.Object
  extended by org.norther.tammi.acorn.util.concurrent.TimerDaemon
All Implemented Interfaces:
ScheduledTimer

public class TimerDaemon
extends Object
implements ScheduledTimer

A general-purpose time-based daemon implementation of ScheduledTimer, vaguely similar in functionality to base system-level utilities such as at (and the associated crond) in Unix.

Objects of this class maintain a single thread and a task queue that may be used to execute Runnable commands in any of three modes -- absolute (run at a given time), relative (run after a given delay), and periodic (cyclically run with a given delay).

All commands are executed by the single background thread. The thread is not actually started until the first request is encountered. Also, if the thread is stopped for any reason, one is started upon encountering the next request, or restart() is invoked.

If you would instead like commands run in their own threads, you can use as arguments Runnable commands that start their own threads (or perhaps wrap within ThreadedExecutors).

You can also use multiple daemon objects, each using a different background thread. However, one of the reasons for using a time daemon is to pool together processing of infrequent tasks using a single background thread.

Background threads are created using a ThreadFactory. The default factory does not automatically setDaemon status.

The class uses Java timed waits for scheduling. These can vary in precision across platforms, and provide no real-time guarantees about meeting deadlines.

Based on Doug Lea's ClockDaemon .

Version:
$Id: TimerDaemon.java,v 1.12 2009/09/28 15:08:49 cvsimp Exp $
Author:
Doug Lea, Ilkka Priha

Constructor Summary
TimerDaemon()
          Constructs a new daemon.
TimerDaemon(ThreadFactory tf)
          Constructs a new daemon with a factory.
 
Method Summary
protected  void clearThread()
          Sets thread to null to indicate termination
<T> Future<T>
executeAfterDelay(Callable<T> command, long delay)
          Excecutes the given callable command after waiting for the given delay.
 Future<?> executeAfterDelay(Runnable command, long delay)
          Excecutes the given command after waiting for the given delay.
<T> Future<T>
executeAt(Callable<T> command, Date date)
          Executes the given callable command at the given time.
 Future<?> executeAt(Runnable command, Date date)
          Executes the given command at the given time.
 Future<?> executePeriodically(Runnable command, Date date, long period)
          Executes the given command every period milliseconds starting at the given time.
 Future<?> executePeriodically(Runnable command, long period, boolean startNow)
          Executes the given command every period milliseconds.
 Future<?> executePeriodically(Runnable command, long delay, long period)
          Executes the given command every period milliseconds after waiting for the given delay.
 Runnable getIdleCommand()
          Gets the idle command.
 long getIdleDelay()
          Gets the idle delay.
 Thread getThread()
          Gets the thread being used to process commands, or null if there is no such thread.
 ThreadFactory getThreadFactory()
          Gets the thread factory.
 boolean isIdleSupported()
          Checks whether idle commands are supported by this timer.
 void setIdleCommand(Runnable command)
          Sets the idle command.
 void setIdleDelay(long delay)
          Sets the idle delay.
 void setThreadFactory(ThreadFactory tf)
          Sets the thread factory.
 void start()
          Starts (or restarts) a thread to process commands, or wake up an existing thread if one is already running.
 void stop()
          Cancels all tasks and interrupts the background thread executing the current task, if any.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

TimerDaemon

public TimerDaemon()
Constructs a new daemon.


TimerDaemon

public TimerDaemon(ThreadFactory tf)
Constructs a new daemon with a factory.

Parameters:
tf - the thread factory.
Method Detail

isIdleSupported

public boolean isIdleSupported()
Description copied from interface: ScheduledTimer
Checks whether idle commands are supported by this timer.

Specified by:
isIdleSupported in interface ScheduledTimer
Returns:
true if idle is supported, false otherwise.

getIdleCommand

public Runnable getIdleCommand()
Description copied from interface: ScheduledTimer
Gets the idle command.

Specified by:
getIdleCommand in interface ScheduledTimer
Returns:
the idle command or null.

setIdleCommand

public void setIdleCommand(Runnable command)
Description copied from interface: ScheduledTimer
Sets the idle command.

Specified by:
setIdleCommand in interface ScheduledTimer
Parameters:
command - the idle command.

getIdleDelay

public long getIdleDelay()
Description copied from interface: ScheduledTimer
Gets the idle delay.

Specified by:
getIdleDelay in interface ScheduledTimer
Returns:
the idle delay in msecs.

setIdleDelay

public void setIdleDelay(long delay)
Description copied from interface: ScheduledTimer
Sets the idle delay.

Specified by:
setIdleDelay in interface ScheduledTimer
Parameters:
delay - the idle delay in msecs.

executeAt

public Future<?> executeAt(Runnable command,
                           Date date)
Description copied from interface: ScheduledTimer
Executes the given command at the given time.

Specified by:
executeAt in interface ScheduledTimer
Parameters:
command - the command to run at the given time.
date - the absolute time to run the command.
Returns:
a cancellable task.

executeAfterDelay

public Future<?> executeAfterDelay(Runnable command,
                                   long delay)
Description copied from interface: ScheduledTimer
Excecutes the given command after waiting for the given delay.

Sample Usage. You can use a ClockDaemon to arrange timeout callbacks to break out of stuck IO. For example (code sketch):

 class X
 {
     ...
     ScheduledTimer timer = ...
     Thread readerThread;
     FileInputStream datafile;
  
     void startReadThread()
     {
         datafile = new FileInputStream("data", ...);
         readerThread = new Thread(new Runnable()
         {
             public void run()
             {
                 for(;;)
                 {
                     // Try to gracefully exit before blocking.
                     if (Thread.currentThread().isInterrupted())
                     {
                         quietlyWrapUpAndReturn();
                     }
                     else
                     {
                         try
                         {
                             int c = datafile.read();
                             if (c == -1)
                             {
                                 break;
                             }
                             else
                             {
                                 process(c);
                             }
                         }
                         catch (IOException x)
                         {
                             cleanup();
                             return;
                         }
                     }
                 }
             }
         };
         readerThread.start();
         // Establish callback to cancel after 60 seconds.
         timer.executeAfterDelay(new Runnable()
         {
             public void run()
             {
                 readerThread.interrupt();  // try to interrupt thread
                 datafile.close();  // force thread to lose its input file
             }
         }, 60000);
     }
 }
 

Specified by:
executeAfterDelay in interface ScheduledTimer
Parameters:
command - the command to run after the delay.
delay - the delay from now to run the command in msecs.
Returns:
a cancellable task.

executePeriodically

public Future<?> executePeriodically(Runnable command,
                                     long period,
                                     boolean startNow)
Description copied from interface: ScheduledTimer
Executes the given command every period milliseconds. If startNow is true, execution begins immediately, otherwise, it begins after the first period delay.

Sample Usage . Here is one way to update Swing components acting as progress indicators for long-running actions.

 class X
 {
     JLabel statusLabel = ...;
     int percentComplete = 0;
     synchronized int  getPercentComplete() { return percentComplete; }
     synchronized void setPercentComplete(int p) { percentComplete = p; }
  
     ScheduledTimer timer = ...;
     void startWorking()
     {
         Runnable showPct = new Runnable()
         {
             public void run()
             {
                 SwingUtilities.invokeLater(new Runnable()
                 {
                     public void run()
                     {
                         statusLabel.
                             setText(getPercentComplete() + "%");
                     }
                 }
             }
         };
  
         final Future updater = timer.executePeriodically(showPct, 500, true);
         Runnable action = new Runnable()
         {
             public void run()
             {
                 for (int i = 0; i < 100; ++i)
                 {
                     work();
                     setPercentComplete(i);
                 }
                 updater.cancel();
             }
         };
  
         new Thread(action).start();
     }
 }
 

Specified by:
executePeriodically in interface ScheduledTimer
Parameters:
command - the command to run at each cycle.
period - the period, in msecs. Periods are measured from start-of-task to the next start-of-task. It is generally a bad idea to use a period that is shorter than the expected task duration.
startNow - true if the cycle should start with execution of the task now. Otherwise, the cycle starts with a delay of period milliseconds.
Returns:
a cancellable task.

executePeriodically

public Future<?> executePeriodically(Runnable command,
                                     Date date,
                                     long period)
Description copied from interface: ScheduledTimer
Executes the given command every period milliseconds starting at the given time.

Specified by:
executePeriodically in interface ScheduledTimer
Parameters:
command - the runnable to execute.
date - the startnig date.
period - the period.
Returns:
a cancellable task.

executePeriodically

public Future<?> executePeriodically(Runnable command,
                                     long delay,
                                     long period)
Description copied from interface: ScheduledTimer
Executes the given command every period milliseconds after waiting for the given delay.

Specified by:
executePeriodically in interface ScheduledTimer
Parameters:
command - the runnable to execute.
delay - the delay in msecs.
period - the period.
Returns:
a cancellable task.

executeAt

public <T> Future<T> executeAt(Callable<T> command,
                               Date date)
Description copied from interface: ScheduledTimer
Executes the given callable command at the given time.

Specified by:
executeAt in interface ScheduledTimer
Type Parameters:
T - the result type.
Parameters:
command - the command to run at the given time.
date - the absolute time to run the command.
Returns:
a cancellable task.

executeAfterDelay

public <T> Future<T> executeAfterDelay(Callable<T> command,
                                       long delay)
Description copied from interface: ScheduledTimer
Excecutes the given callable command after waiting for the given delay.

Specified by:
executeAfterDelay in interface ScheduledTimer
Type Parameters:
T - the result type.
Parameters:
command - the command to run after the delay.
delay - the delay from now to run the command in msecs.
Returns:
a cancellable task.

start

public void start()
Description copied from interface: ScheduledTimer
Starts (or restarts) a thread to process commands, or wake up an existing thread if one is already running. This method can be invoked if the background thread crashed due to an unrecoverable exception in an executed command.

Specified by:
start in interface ScheduledTimer

stop

public void stop()
Description copied from interface: ScheduledTimer
Cancels all tasks and interrupts the background thread executing the current task, if any. A new background thread will be started if new execution requests are encountered. If the currently executing task does not repsond to interrupts, the current thread may persist, even if a new thread is started via restart().

Specified by:
stop in interface ScheduledTimer

getThread

public Thread getThread()
Gets the thread being used to process commands, or null if there is no such thread. You can use this to invoke any special methods on the thread, for example, to interrupt it.

Returns:
the thread or null.

getThreadFactory

public ThreadFactory getThreadFactory()
Gets the thread factory.

Returns:
the thread factory.

setThreadFactory

public void setThreadFactory(ThreadFactory tf)
Sets the thread factory.

Parameters:
tf - the thread factory.

clearThread

protected void clearThread()
Sets thread to null to indicate termination



Copyright © 2004 The Norther Organization. All rights reserved.