Widening.

git-svn-id: https://samskivert.googlecode.com/svn/trunk@2127 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2007-07-10 22:08:54 +00:00
parent c20cea85dd
commit a8218d725a
+33 -42
View File
@@ -26,34 +26,32 @@ import java.util.TimerTask;
import com.samskivert.Log; import com.samskivert.Log;
/** /**
* An interface for doing operations after some delay. Allows expiration * An interface for doing operations after some delay. Allows expiration to occur on a specific
* to occur on a specific thread, and guarantees that any queued expiration * thread, and guarantees that any queued expiration will not run if the Interval has since been
* will not run if the Interval has since been cancelled or rescheduled. * cancelled or rescheduled.
*/ */
public abstract class Interval public abstract class Interval
{ {
/** /**
* An interface that will be implemented by the runnable posted * An interface that will be implemented by the runnable posted to a RunQueue that can be used
* to a RunQueue that can be used to retrieve the original Interval. * to retrieve the original Interval.
*/ */
public static interface RunBuddy extends Runnable public static interface RunBuddy extends Runnable
{ {
/** /**
* Retrieve the Interval that is responsible for posting this * Retrieve the Interval that is responsible for posting this RunBuddy to a RunQueue. Most
* RunBuddy to a RunQueue. Most likely used to call toString() * likely used to call toString() on the Interval for logging purposes.
* on the Interval for logging purposes.
*/ */
public Interval getInterval (); public Interval getInterval ();
} }
/** /**
* Clears out the {@link Timer} currently being used to schedule * Clears out the {@link Timer} currently being used to schedule intervals. This method is
* intervals. This method is normally not needed as a single timer thread * normally not needed as a single timer thread can be used for the lifetime of the VM, but in
* can be used for the lifetime of the VM, but in certain situations (in * certain situations (in applets) the timer thread will be forcibly killed when the applet is
* applets) the timer thread will be forcibly killed when the applet is * destroyed but the classes will not be unloaded. In that case, the applet should call this
* destroyed but the classes will not be unloaded. In that case, the applet * method in its own destroy method. A new timer thread will then be created the next time an
* should call this method in its own destroy method. A new timer thread * interval is scheduled.
* will then be created the next time an interval is scheduled.
*/ */
public static synchronized void resetTimer () public static synchronized void resetTimer ()
{ {
@@ -61,16 +59,15 @@ public abstract class Interval
} }
/** /**
* Create a simple interval that does not use a RunQueue to run * Create a simple interval that does not use a RunQueue to run the {@link #expired} method.
* the expired() method.
*/ */
public Interval () public Interval ()
{ {
} }
/** /**
* Create an Interval that uses the specified RunQueue to run * Create an Interval that uses the specified {@link RunQueue} to run the {@link #expired}
* the expired() method. * method.
*/ */
public Interval (RunQueue runQueue) public Interval (RunQueue runQueue)
{ {
@@ -82,15 +79,13 @@ public abstract class Interval
} }
/** /**
*
* The main method where your interval should do its work. * The main method where your interval should do its work.
*
*/ */
public abstract void expired (); public abstract void expired ();
/** /**
* Schedule the interval to execute once, after the specified delay. * Schedule the interval to execute once, after the specified delay. Supersedes any previous
* Supersedes any previous schedule that this Interval may have had. * schedule that this Interval may have had.
*/ */
public final void schedule (long delay) public final void schedule (long delay)
{ {
@@ -98,8 +93,8 @@ public abstract class Interval
} }
/** /**
* Schedule the interval to execute repeatedly, with the same delay. * Schedule the interval to execute repeatedly, with the same delay. Supersedes any previous
* Supersedes any previous schedule that this Interval may have had. * schedule that this Interval may have had.
*/ */
public final void schedule (long delay, boolean repeat) public final void schedule (long delay, boolean repeat)
{ {
@@ -107,9 +102,8 @@ public abstract class Interval
} }
/** /**
* Schedule the interval to execute repeatedly with the specified * Schedule the interval to execute repeatedly with the specified initial delay and repeat
* initial delay and repeat delay. * delay. Supersedes any previous schedule that this Interval may have had.
* Supersedes any previous schedule that this Interval may have had.
*/ */
public final void schedule (long initialDelay, long repeatDelay) public final void schedule (long initialDelay, long repeatDelay)
{ {
@@ -125,8 +119,8 @@ public abstract class Interval
} }
/** /**
* Cancel the current schedule, and ensure that any expirations that * Cancel the current schedule, and ensure that any expirations that are queued up but have not
* are queued up but have not yet run do not run. * yet run do not run.
*/ */
public final void cancel () public final void cancel ()
{ {
@@ -152,17 +146,15 @@ public abstract class Interval
} }
} else { } else {
// If the task has been defanged, we go ahead and try cancelling // If the task has been defanged, we go ahead and try cancelling it again. The reason
// it again. The reason for this is that it's possible // for this is that it's possible to have a runaway task if two threads call schedule()
// to have a runaway task if two threads call schedule() and // and cancel() at the same time.
// cancel() at the same time.
// 1) ThreadA calls cancel() and gets a handle on taskA, yields. // 1) ThreadA calls cancel() and gets a handle on taskA, yields.
// 2) ThreadB calls schedule(), gets a handle on taskA, cancel()s, // 2) ThreadB calls schedule(), gets a handle on taskA, cancel()s, which sets _task to
// which sets _task to null, then sets up taskB, returns. // null, then sets up taskB, returns.
// 3) ThreadA resumes, sets _task to null and re-cancels taskA. // 3) ThreadA resumes, sets _task to null and re-cancels taskA. taskB is now an active
// taskB is now an active TimerTask but is not referenced anywhere. // TimerTask but is not referenced anywhere. In case this is taskB, we cancel it so
// In case this is taskB, we cancel it so that it doesn't // that it doesn't ineffectually expire repeatedly until the JVM exists.
// ineffectually expire repeatedly until the JVM exists.
task.cancel(); task.cancel();
} }
} }
@@ -209,8 +201,7 @@ public abstract class Interval
protected RunBuddy _runner; protected RunBuddy _runner;
} }
/** If non-null, the RunQueue used to run the expired() method for each /** If non-null, the RunQueue used to run the expired() method for each Interval. */
* Interval. */
protected RunQueue _runQueue; protected RunQueue _runQueue;
/** The task that actually schedules our execution with the static Timer. */ /** The task that actually schedules our execution with the static Timer. */