I’m using this code to Schedule a Task in my Java 8 Spring WebApp:
In a @Controller;
@EventListener(ContextRefreshedEvent.class) public void doSomethingAfterContextRefreshed() { ScheduledFuture<?> countdown = scheduler.schedule(new Runnable() { @Override public void run() { try { Execute(); } catch (IOException e) { e.printStackTrace(); } }}, 10, TimeUnit.SECONDS); while (!countdown.isDone()) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } scheduler.shutdown(); }
When the App starts, the Execute()
method gets called 10 seconds after startup with no errors, but after it completes I get the following stack trace:
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@52518e6[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@759546c8[Wrapped task = com.mycompany.myproject.service.LoadService$1@4871ba3f]] rejected from java.util.concurrent.ScheduledThreadPoolExecutor@798daafa[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1] at java.base/java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2055) at java.base/java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:825) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:340) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:562)
Any ideas why I get this exception?
Advertisement
Answer
Let’s simplify this:
public class DeleteMe { public static void main(String[] args) { doSomethingAfterContextRefreshed(); doSomethingAfterContextRefreshed(); } static ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(1); public static void doSomethingAfterContextRefreshed() { ScheduledFuture<?> countdown = scheduler.schedule(new Runnable() { @Override public void run() { System.out.println("Some message"); }}, 100, TimeUnit.MILLISECONDS); while (!countdown.isDone()) { LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10)); } scheduler.shutdown(); } }
At the end of the first invocation of doSomethingAfterContextRefreshed
– what do you do? scheduler.shutdown();
.
At the second invocation of doSomethingAfterContextRefreshed();
what do you do? scheduler.schedule(....)
.
Is the scheduler
shutdown at this point in time? What does the documentation of schedule
says to throw in such cases? You have your answer now.