|
Jumpi v1.2.0 | |||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--org.jumpi.impl.timer.TimerImpl
Simple timer implementation.
A general-purpose time-based daemon, vaguely similar in functionality to
common 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.
[ Introduction to this package. ]
Constructor Summary | |
TimerImpl()
|
Method Summary | |
void |
cancel(java.lang.Object taskID)
Cancel a scheduled task that has not yet been run. |
void |
configure(java.lang.String name,
Properties props)
Configure the TimerImpl. |
java.lang.String |
getName()
Get the fully qualified name of the instance. |
java.lang.String |
getTaskId()
The taskId is set to the TimerImpl's name, since there is only one timer in the Jumpi component tree, and the Component name is unique. |
java.lang.Object |
interruptAfterDelay(long millisecondsToDelay,
TimerListener listener)
Excecute the given command after waiting for the given delay. |
java.lang.Object |
interruptAt(long time,
TimerListener listener)
Execute the given command at the given time. |
java.lang.Object |
interruptPeriodically(long period,
TimerListener listener,
boolean startNow)
Execute the given command every period milliseconds. |
boolean |
isLongRunning()
The TimerImpl task is long running, since the task runs in an infinite loop waiting to notify the registered TimerListeners when timers have triggered. |
boolean |
isSchedulable()
Whether the task is schedulable, i.e. run() should be called because there is work to do. |
void |
manage(Component root,
Component parent,
java.lang.String operation,
java.util.Hashtable parameters)
Perform a recursive management operation through the Jumpi component tree, using the parameters provided. |
void |
run()
Loop indefinitely getting tasks to interrupt, and interrupting them until stopped. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructor Detail |
public TimerImpl()
Method Detail |
public void configure(java.lang.String name, Properties props) throws java.lang.Exception
The following configuration attributes are defined:
initheapsize - optional integer [1..MAX-INT] default 10
The initial size of the timer heap.
configure
in interface Configurable
name
- the fully qualified instance name.props
- the read-only properties to configure the instance with.
java.lang.Exception
- when configuration is unsuccessful.
java.lang.IllegalArgumentException
- if name or props are missing.public void manage(Component root, Component parent, java.lang.String operation, java.util.Hashtable parameters) throws java.lang.Exception
The following management actions are handled:
manage
in interface Manageable
root
- the Jumpi instance at the root of the component tree.parent
- the immediate parent of the component.operation
- the operation.parameters
- the operation parameters.
java.lang.Exception
- if any failure to perform management occurs.
java.lang.IllegalArgumentException
- when parameters are missing.public java.lang.String getName()
getName
in interface Configurable
configure(java.lang.String, org.jumpi.spi.Properties)
public java.lang.String getTaskId()
getTaskId
in interface Task
getName()
public boolean isSchedulable()
isSchedulable
in interface Task
public boolean isLongRunning()
isLongRunning
in interface Task
public java.lang.Object interruptAt(long time, TimerListener listener)
interruptAt
in interface Timer
time
- -- the absolute time to run the command, expressed as a
java.util.Date.listener
- -- the listener to interrupt at the given time.
java.lang.IllegalArgumentException
- if listener is null.
java.lang.IllegalStateException
- if not started.Timer.cancel(java.lang.Object)
,
TimerListener.handleTimerInterrupt()
public java.lang.Object interruptAfterDelay(long millisecondsToDelay, TimerListener listener)
Sample Usage. You can use a TimerImpl to arrange timeout callbacks to break out of stuck IO. For example (code sketch):
class X { ... TimerImpl 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 ex) { cleanup(); return; } } } }; readerThread.start(); // establish callback to cancel after 60 seconds timer.executeAfterDelay(60000, new Runnable() { readerThread.interrupt(); // try to interrupt thread datafile.close(); // force thread to lose its input file }); } }
interruptAfterDelay
in interface Timer
millisecondsToDelay
- -- the number of milliseconds from now to run
the command.listener
- -- the listener to interrupt after the delay.
java.lang.IllegalArgumentException
- if listener is null.
java.lang.IllegalStateException
- if not started.Timer.cancel(java.lang.Object)
,
TimerListener.handleTimerInterrupt()
public java.lang.Object interruptPeriodically(long period, TimerListener listener, boolean startNow)
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; } TimerImpl cd = ...; void startWorking() { Runnable showPct = new Runnable() { public void run() { SwingUtilities.invokeLater(new Runnable() { public void run() { statusLabel.setText(getPercentComplete() + "%"); } } } }; final Object updater = cd.executePeriodically(500, showPct, true); Runnable action = new Runnable() { public void run() { for (int i = 0; i < 100; ++i) { work(); setPercentComplete(i); } cd.cancel(updater); } }; new Thread(action).start(); } }
interruptPeriodically
in interface Timer
period
- -- the period, in milliseconds. 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.listener
- -- the listener to interrupt at each cyclestartNow
- -- true if the cycle should start with execution of the
task now. Otherwise, the cycle starts with a delay of
period
milliseconds.
java.lang.IllegalArgumentException
- if period less than or equal to
zero, or listener is null.
java.lang.IllegalStateException
- if not started.Timer.cancel(java.lang.Object)
,
TimerListener.handleTimerInterrupt()
public void cancel(java.lang.Object taskID)
cancel
in interface Timer
taskID
- -- a task reference returned by one of the execute
commands
java.lang.IllegalArgumentException
- if the taskID is nullpublic void run()
run
in interface java.lang.Runnable
|
Jumpi v1.2.0 | |||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |