269 |
|
* Overrides FutureTask version so as to reset/requeue if periodic. |
270 |
|
*/ |
271 |
|
public void run() { |
272 |
< |
boolean periodic = isPeriodic(); |
273 |
< |
if (!canRunInCurrentRunState(periodic)) |
272 |
> |
if (!canRunInCurrentRunState(this)) |
273 |
|
cancel(false); |
274 |
< |
else if (!periodic) |
274 |
> |
else if (!isPeriodic()) |
275 |
|
super.run(); |
276 |
|
else if (super.runAndReset()) { |
277 |
|
setNextRunTime(); |
281 |
|
} |
282 |
|
|
283 |
|
/** |
284 |
< |
* Returns true if can run a task given current run state |
285 |
< |
* and run-after-shutdown parameters. |
287 |
< |
* |
288 |
< |
* @param periodic true if this task periodic, false if delayed |
284 |
> |
* Returns true if can run a task given current run state and |
285 |
> |
* run-after-shutdown parameters. |
286 |
|
*/ |
287 |
< |
boolean canRunInCurrentRunState(boolean periodic) { |
288 |
< |
return isRunningOrShutdown(periodic ? |
289 |
< |
continueExistingPeriodicTasksAfterShutdown : |
290 |
< |
executeExistingDelayedTasksAfterShutdown); |
287 |
> |
boolean canRunInCurrentRunState(RunnableScheduledFuture<?> task) { |
288 |
> |
if (!isShutdown()) |
289 |
> |
return true; |
290 |
> |
if (isStopped()) |
291 |
> |
return false; |
292 |
> |
return task.isPeriodic() |
293 |
> |
? continueExistingPeriodicTasksAfterShutdown |
294 |
> |
: (executeExistingDelayedTasksAfterShutdown |
295 |
> |
|| task.getDelay(NANOSECONDS) <= 0); |
296 |
|
} |
297 |
|
|
298 |
|
/** |
311 |
|
reject(task); |
312 |
|
else { |
313 |
|
super.getQueue().add(task); |
314 |
< |
if (isShutdown() && |
313 |
< |
!canRunInCurrentRunState(task.isPeriodic()) && |
314 |
< |
remove(task)) |
314 |
> |
if (!canRunInCurrentRunState(task) && remove(task)) |
315 |
|
task.cancel(false); |
316 |
|
else |
317 |
|
ensurePrestart(); |
325 |
|
* @param task the task |
326 |
|
*/ |
327 |
|
void reExecutePeriodic(RunnableScheduledFuture<?> task) { |
328 |
< |
if (canRunInCurrentRunState(true)) { |
328 |
> |
if (canRunInCurrentRunState(task)) { |
329 |
|
super.getQueue().add(task); |
330 |
< |
if (!canRunInCurrentRunState(true) && remove(task)) |
331 |
< |
task.cancel(false); |
332 |
< |
else |
330 |
> |
if (canRunInCurrentRunState(task) || !remove(task)) { |
331 |
|
ensurePrestart(); |
332 |
+ |
return; |
333 |
+ |
} |
334 |
|
} |
335 |
+ |
task.cancel(false); |
336 |
|
} |
337 |
|
|
338 |
|
/** |
345 |
|
getExecuteExistingDelayedTasksAfterShutdownPolicy(); |
346 |
|
boolean keepPeriodic = |
347 |
|
getContinueExistingPeriodicTasksAfterShutdownPolicy(); |
348 |
< |
if (!keepDelayed && !keepPeriodic) { |
349 |
< |
for (Object e : q.toArray()) |
350 |
< |
if (e instanceof RunnableScheduledFuture<?>) |
351 |
< |
((RunnableScheduledFuture<?>) e).cancel(false); |
352 |
< |
q.clear(); |
353 |
< |
} |
354 |
< |
else { |
355 |
< |
// Traverse snapshot to avoid iterator exceptions |
356 |
< |
for (Object e : q.toArray()) { |
357 |
< |
if (e instanceof RunnableScheduledFuture) { |
358 |
< |
RunnableScheduledFuture<?> t = |
359 |
< |
(RunnableScheduledFuture<?>)e; |
359 |
< |
if ((t.isPeriodic() ? !keepPeriodic : !keepDelayed) || |
360 |
< |
t.isCancelled()) { // also remove if already cancelled |
361 |
< |
if (q.remove(t)) |
362 |
< |
t.cancel(false); |
363 |
< |
} |
348 |
> |
// Traverse snapshot to avoid iterator exceptions |
349 |
> |
// TODO: implement and use efficient removeIf |
350 |
> |
// super.getQueue().removeIf(...); |
351 |
> |
for (Object e : q.toArray()) { |
352 |
> |
if (e instanceof RunnableScheduledFuture) { |
353 |
> |
RunnableScheduledFuture<?> t = (RunnableScheduledFuture<?>)e; |
354 |
> |
if ((t.isPeriodic() |
355 |
> |
? !keepPeriodic |
356 |
> |
: (!keepDelayed && t.getDelay(NANOSECONDS) > 0)) |
357 |
> |
|| t.isCancelled()) { // also remove if already cancelled |
358 |
> |
if (q.remove(t)) |
359 |
> |
t.cancel(false); |
360 |
|
} |
361 |
|
} |
362 |
|
} |