2

I'm creating an executor using:

    executor = Executors.newScheduledThreadPool(0, (r) -> new Thread(r, "Scheduler"));

I'm scheduling 2 tasks, each running once then once on a daily interval

  long seconds = Duration.between(now, s.scheduledRunTime).getSeconds();
  if (seconds <= 0) {
    seconds += TimeUnit.DAYS.toSeconds(1);
  }

  LOG.info("Scheduling " + s.target + " to run immediately and then every day at " + s.scheduledRunTime + " (first " + seconds + " seconds from now)");
  executor.execute(() -> execute(s));
  executor.scheduleAtFixedRate(() -> execute(s), seconds, TimeUnit.DAYS.toSeconds(1), TimeUnit.SECONDS);

The tasks perform their initial run correctly, I can see in the logs that they've started and completed in a reasonable timeframe. (One takes 39 seconds, one 16 seconds if it matters).

The tasks also perform their scheduled run correctly if I wait for the time.

Everything works fine on my Windows development environment (JavaSE-1.8 (jdk1.8.0_45) from Eclipse), however once deployed to Linux running on Java 1.8.0_40 I see the thread called Scheduler spinning on 100% CPU permanently.

I've not tried to shutdown the scheduler (research showed that during shutdown this sometimes happened but that isn't the case here).

The stack trace is:

Thread[Scheduler,5,app] RUNNABLE
CPU (msecs) = 15020099
java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.poll(ScheduledThreadPoolExecutor.java:809)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)

Does anyone know what is causing this thread to spin using 100% CPU?

I've tried refreshing many times and the stack trace never shows anything other than the above.

Tim B
  • 40,716
  • 16
  • 83
  • 128
  • What Java version are you running on on your dev environment? – Jurgen Camilleri May 15 '18 at 16:03
  • JavaSE-1.8 (jdk1.8.0_45) - so slightly different but not drastically so. – Tim B May 15 '18 at 16:10
  • I'm asking as there's a bug in Java 8 which describes your issue exactly [JDK-8129861](https://bugs.openjdk.java.net/browse/JDK-8129861). Try upgrading to JDK9 and see if it's resolved for you. Another person commented on the bug that he did not reproduce the issue on 8u45, so it's worth a shot. – Jurgen Camilleri May 15 '18 at 16:14
  • @JurgenCamilleri That does look like an exact match! I'll do some testing tomorrow and get back to you but it might well be worth writing that as an answer. – Tim B May 15 '18 at 16:36
  • Note that JDK8 update 45 is pretty old, you might want to check update 171 or 172 to see if the fix was backported. – Mark Rotteveel May 15 '18 at 19:39

1 Answers1

3

Your code is fine; I suspect you are encountering an issue because you're using 0 core threads (the first parameter to newScheduledThreadPool).

There is a known bug in Java 8 which describes this issue. JDK 9 fixes this particular bug. Another comment on the bug report suggests that the issue was not reproduced on 8u45 (which is your working environment version), so I suggest starting out by upgrading your JDK - I'm fairly confident this will resolve your issue.

Jurgen Camilleri
  • 3,559
  • 20
  • 45
  • 3
    I went with the very simple expedient of changing the 0 to a 1 and when the new version deployed overnight the graph immediately dropped back to zero. Thanks a lot :) – Tim B May 16 '18 at 08:13