How to identify if cancelled ScheduledFuture is actually not cancelled?

You can accomplish your goal with the following:

  • A Set<Runnable> that keeps track of Runnables that have begun execution by the thread pool.
  • A Map<ScheduledFuture<?>, Runnable> that maps a ScheduledFuture<?> to its respective Runnable.
    • After scheduling the task, you should immediately add the ScheduledFuture and its respective Runnable to the Map.
    • If this insertion into the Map is performed atomically with scheduling the task itself, then you can avoid the edge case that the ScheduledFuture was never added to the Map even after it was cancelled.

I recommend changing your ScheduledExecutorService to a ScheduledThreadPoolExecutor, which will allow you to override its beforeExecute(Thread, Runnable) method; this method is invoked immediately before the task is run by the pool after it has already been assigned a thread that will execute the task.

When overriding this method, you can add the Runnable to your Set<Runnable>.

Then, when a ScheduledFuture is cancelled, you can call set.contains(map.get(future)), which tells you if the Runnable (that the ScheduledFuture maps to) was executed.


Note that your Set<Runnable> and Map<ScheduledFuture<?>, Runnable> implementations may have to be made thread-safe to avoid possible race conditions.