FULL PRODUCT VERSION :
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
ExecutorService.awaitTermination() is supposed to block "until all tasks have completed execution after a shutdown request" yet the testcase demonstrates a case where this is not true (the executor blocks forever).
Proposed fix: ScheduledThreadPoolExecutor.ScheduledFutureTask.cancel() should fire ThreadPoolExecutor.interruptIdleWorkers()
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run testcase
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The executor should shut down once the scheduled task is cancelled.
ACTUAL -
The executor blocks forever.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
Enable ScheduledThreadPoolExecutor.setRemoveOnCancelPolicy() but this was only added in JDK 7public class Testcase
{
public static void main(String[] args) throws InterruptedException
{
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> future = executor.schedule(new Callable<Void>()
{
@Override
public Void call() throws Exception
{
System.out.println("Task ran!");
return null;
}
}, 1, TimeUnit.DAYS);
executor.shutdown();
boolean cancelled = future.cancel(false);
// future.cancel() returns success
assert (cancelled);
if (cancelled)
System.out.println("Task successfully cancelled");
else
System.out.println("Task cannot be cancelled");
try
{
// The worker thread prevents the executor from shutting down even though all tasks are
// cancelled.
System.out.println("Waiting for executor to shut down...");
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
System.out.println("Executor successfully shut down...");
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}