我使用以下方法创建执行程序:
executor = Executors.newScheduledThreadPool(0, (r) -> new Thread(r, "Scheduler"));
我安排了2个任务,每个任务每天运行一次,然后每天运行一次
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);
任务正确执行初始运行,我可以在日志中看到他们已在合理的时间范围内启动和完成。 (一个需要39秒,如果重要则需要16秒)。
如果我等待时间,任务也会正确执行预定的运行。
在我的Windows开发环境(Eclipse的JavaSE-1.8(jdk1.8.0_45))上一切正常,但是一旦部署到运行在Java 1.8.0_40上的Linux,我看到名为Scheduler的线程永久地在100%CPU上旋转。 / p>
我没有尝试关闭调度程序(研究表明,在关机期间,这种情况有时会发生,但现在情况并非如此)。
堆栈跟踪是:
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)
有没有人知道是什么原因导致这个线程使用100%CPU旋转?
我尝试过多次刷新,堆栈跟踪从不显示上述内容。
答案 0 :(得分:2)
你的代码很好;我怀疑你遇到了一个问题,因为你正在使用0个核心线程(newScheduledThreadPool
的第一个参数)。
Java 8中存在一个已知的错误,它描述了this issue。 JDK 9修复了这个特殊的bug。关于错误报告的另一个评论表明该问题没有在8u45(这是你的工作环境版本)上重现,所以我建议首先升级你的JDK - 我相当有信心这将解决你的问题。