代码之家  ›  专栏  ›  技术社区  ›  Tim B

Java ScheduledExecutorService 100%运行一个CPU核,但不执行任务[重复]

  •  2
  • Tim B  · 技术社区  · 8 年前

    我正在使用以下方法创建遗嘱执行人:

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

    我安排了两个任务,每个任务运行一次,然后每天间隔一次

      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\u 45))上,一切都很好,但是一旦部署到运行在Java 1.8.0\u 40上的Linux上,我就会看到名为Scheduler的线程在100%CPU上永久旋转。

    我没有尝试关闭调度器(研究表明,在关闭过程中有时会发生这种情况,但这里的情况并非如此)。

    堆栈跟踪是:

    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旋转吗?

    我尝试过多次刷新,堆栈跟踪只显示上述内容。

    1 回复  |  直到 8 年前
        1
  •  3
  •   Jurgen Camilleri    8 年前

    您的代码很好;我怀疑您遇到了一个问题,因为您使用的是0个核心线程(第一个参数 newScheduledThreadPool )。

    Java 8中有一个已知的bug,它描述了 this issue .JDK 9修复了这个特定的bug。关于bug报告的另一条评论表明,8u45(这是您的工作环境版本)上没有再现该问题,因此我建议从升级您的JDK开始,我相信这将解决您的问题。