51 |
|
*/ |
52 |
|
private static final AtomicLong sequencer = new AtomicLong(0); |
53 |
|
|
54 |
< |
private static class ScheduledFutureTask<V> |
54 |
> |
private class ScheduledFutureTask<V> |
55 |
|
extends FutureTask<V> implements ScheduledFuture<V> { |
56 |
|
|
57 |
|
/** Sequence number to break ties FIFO */ |
63 |
|
/** true if at fixed rate; false if fixed delay */ |
64 |
|
private final boolean rateBased; |
65 |
|
|
66 |
– |
|
66 |
|
/** |
67 |
|
* Creates a one-shot action with given nanoTime-based trigger time |
68 |
|
*/ |
136 |
|
} |
137 |
|
|
138 |
|
/** |
139 |
< |
* Overrides FutureTask version so as to reset if periodic. |
139 |
> |
* Overrides FutureTask version so as to reset/requeue if periodic. |
140 |
|
*/ |
141 |
|
public void run() { |
142 |
< |
if (isPeriodic()) |
143 |
< |
runAndReset(); |
144 |
< |
else |
145 |
< |
super.run(); |
146 |
< |
} |
147 |
< |
|
148 |
< |
/** |
149 |
< |
* Return a task (which may be this task) that will trigger in |
150 |
< |
* the period subsequent to current task, or null if |
151 |
< |
* non-periodic or cancelled. |
152 |
< |
*/ |
153 |
< |
ScheduledFutureTask nextTask() { |
154 |
< |
if (period <= 0 || !reset()) |
155 |
< |
return null; |
156 |
< |
time = period + (rateBased ? time : System.nanoTime()); |
157 |
< |
return this; |
142 |
> |
if (!isPeriodic()) |
143 |
> |
ScheduledFutureTask.super.run(); |
144 |
> |
else { |
145 |
> |
ScheduledFutureTask.super.runAndReset(); |
146 |
> |
if (isCancelled()) |
147 |
> |
return; |
148 |
> |
boolean down = isShutdown(); |
149 |
> |
if (!down || |
150 |
> |
(getContinueExistingPeriodicTasksAfterShutdownPolicy() && |
151 |
> |
!isTerminating())) { |
152 |
> |
time = period + (rateBased ? time : System.nanoTime()); |
153 |
> |
ScheduledThreadPoolExecutor.super.getQueue().add(this); |
154 |
> |
} |
155 |
> |
// This might have been the final executed delayed |
156 |
> |
// task. Wake up threads to check. |
157 |
> |
else if (down) |
158 |
> |
interruptIdleWorkers(); |
159 |
> |
} |
160 |
|
} |
161 |
|
} |
162 |
|
|
578 |
|
return super.getQueue(); |
579 |
|
} |
580 |
|
|
580 |
– |
/** |
581 |
– |
* Override of <tt>Executor</tt> hook method to support periodic |
582 |
– |
* tasks. If the executed task was periodic, causes the task for |
583 |
– |
* the next period to execute. |
584 |
– |
* @param r the task (assumed to be a ScheduledFuture) |
585 |
– |
* @param t the exception |
586 |
– |
*/ |
587 |
– |
protected void afterExecute(Runnable r, Throwable t) { |
588 |
– |
super.afterExecute(r, t); |
589 |
– |
ScheduledFutureTask<?> next = ((ScheduledFutureTask<?>)r).nextTask(); |
590 |
– |
if (next != null && |
591 |
– |
(!isShutdown() || |
592 |
– |
(getContinueExistingPeriodicTasksAfterShutdownPolicy() && |
593 |
– |
!isTerminating()))) |
594 |
– |
super.getQueue().add(next); |
595 |
– |
|
596 |
– |
// This might have been the final executed delayed task. Wake |
597 |
– |
// up threads to check. |
598 |
– |
else if (isShutdown()) |
599 |
– |
interruptIdleWorkers(); |
600 |
– |
} |
581 |
|
} |