| java.lang.Object EDU.oswego.cs.dl.util.concurrent.ThreadFactoryUser EDU.oswego.cs.dl.util.concurrent.ClockDaemon
ClockDaemon | public class ClockDaemon extends ThreadFactoryUser (Code) | | 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. ]
|
Inner Class :protected static class TaskNode implements Comparable | |
Inner Class :protected class RunLoop implements Runnable | |
Method Summary | |
public static void | cancel(Object taskID) Cancel a scheduled task that has not yet been run. | protected synchronized void | clearThread() | public Object | executeAfterDelay(long millisecondsToDelay, Runnable command) Excecute 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. | public Object | executeAt(Date date, Runnable command) Execute the given command at the given time.
Parameters: date - -- the absolute time to run the command, expressedas a java.util.Date. Parameters: command - -- the command to run at the given time. | public Object | executePeriodically(long period, Runnable command, boolean startNow) Execute the given command every period milliseconds.
If startNow is true, execution begins immediately,
otherwise, it begins after the first period delay.
Sample Usage. | public synchronized Thread | getThread() Return the thread being used to process commands, or
null if there is no such thread. | protected synchronized TaskNode | nextTask() | public synchronized void | restart() Start (or restart) a thread to process commands, or wake
up an existing thread if one is already running. | public synchronized void | shutDown() Cancel all tasks and interrupt the background thread executing
the current task, if any.
A new background thread will be started if new execution
requests are encountered. |
heap_ | final protected Heap heap_(Code) | | tasks are maintained in a standard priority queue *
|
runLoop_ | final protected RunLoop runLoop_(Code) | | |
thread_ | protected Thread thread_(Code) | | The thread used to process commands *
|
ClockDaemon | public ClockDaemon()(Code) | | Create a new ClockDaemon
|
cancel | public static void cancel(Object taskID)(Code) | | Cancel a scheduled task that has not yet been run.
The task will be cancelled
upon the next opportunity to run it. This has no effect if
this is a one-shot task that has already executed.
Also, if an execution is in progress, it will complete normally.
(It may however be interrupted via getThread().interrupt()).
But if it is a periodic task, future iterations are cancelled.
Parameters: taskID - -- a task reference returned by one ofthe execute commands exception: ClassCastException - if the taskID argument is not of the type returned by an execute command. |
clearThread | protected synchronized void clearThread()(Code) | | set thread_ to null to indicate termination *
|
executeAfterDelay | public Object executeAfterDelay(long millisecondsToDelay, Runnable command)(Code) | | Excecute 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 { ...
ClockDaemon 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
});
}
}
Parameters: millisecondsToDelay - -- the number of millisecondsfrom now to run the command. Parameters: command - -- the command to run after the delay. taskID -- an opaque reference that can be used to cancel execution request |
executeAt | public Object executeAt(Date date, Runnable command)(Code) | | Execute the given command at the given time.
Parameters: date - -- the absolute time to run the command, expressedas a java.util.Date. Parameters: command - -- the command to run at the given time. taskID -- an opaque reference that can be used to cancel execution request |
executePeriodically | public Object executePeriodically(long period, Runnable command, boolean startNow)(Code) | | Execute 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; }
ClockDaemon 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();
}
}
Parameters: period - -- the period, in milliseconds. Periods aremeasured from start-of-task to the next start-of-task. It isgenerally a bad idea to use a period that is shorter than the expected task duration. Parameters: command - -- the command to run at each cycle Parameters: startNow - -- true if the cycle should start with executionof the task now. Otherwise, the cycle starts with a delay ofperiod milliseconds. exception: IllegalArgumentException - if period less than or equal to zero. taskID -- an opaque reference that can be used to cancel execution request |
getThread | public synchronized Thread getThread()(Code) | | Return 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.
|
nextTask | protected synchronized TaskNode nextTask()(Code) | | Return the next task to execute, or null if thread is interrupted *
|
restart | public synchronized void restart()(Code) | | Start (or restart) 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.
|
shutDown | public synchronized void shutDown()(Code) | | Cancel all tasks and interrupt 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().
|
|
|