为什么ScheduledExecutorService.shutdown()使用100%的CPU?

为什么ScheduledExecutorService.shutdown()使用100%的CPU?,第1张

概述为什么ScheduledExecutorService.shutdown()使用100%的CPU?

我有以下简单的代码:

package main; import java.util.concurrent.*; public class Main { public static voID main(String[] args) throws InterruptedException { new Main(); } public Main() throws InterruptedException { scheduledexecutorservice executor = Executors.newScheduledThreadPool(1); executor.schedule(new MyRunnable(),10,TimeUnit.SECONDS); System.out.println("Shutting down..."); executor.shutdown(); System.out.println("Awaiting termination..."); executor.awaitTermination(Long.MAX_VALUE,TimeUnit.MINUTES); System.out.println("Main finished!"); } private class MyRunnable implements Runnable { public voID run() { System.out.println("Finished running!"); } } }

其实,虽然我真正的代码比这个更复杂一点,但我可以把这个问题隔离开来。 代码基本上等待10秒来运行runnable,然后通知主程序的结束。

不过,我注意到了10秒钟,我的一个核心是100%使用。

如果我评论这一行:

在构造函数中引用现有文件时windows Java文件locking?

这个Blocking Queue的实现是否安全?

C并发程序的输出取决于是否输出到标准输出或文件

并发访问文件的linux

使用Nginx或Apache来提供dynamic内容?

executor.awaitTermination(Long.MAX_VALUE,TimeUnit.MINUTES);

cpu核心也是100%使用,主程序也在Runnable之前完成。

如果我评论这一行:

executor.shutdown();

cpu正确使用,但程序不会完成。

如果我注释到前面的两行,那么cpu已经正确使用,但是主程序不能完成。

我的代码有什么问题吗?

是executor.shutdown(); 做一些忙碌的等待,而不是仅仅禁止提交新的任务?

还是应该怪JVM?

更多细节:

$ java -version java version "1.6.0_26" Java(TM) SE Runtime Environment (build 1.6.0_26-b03) Java HotSpot(TM) Server VM (build 20.1-b02,mixed mode) $ uname -a linux XPSG 2.6.32-5-686-bigmem #1 SMP Sun May 6 04:39:05 UTC 2012 i686 GNU/linux

PS:请不要问我使用CountDownLatch或newSingleThreadScheduledExecutor 。 这与我所问的问题无关。 谢谢。

编辑:

这是Java转储:

Full thread dump Java HotSpot(TM) Server VM (20.1-b02 mixed mode): "pool-1-thread-1" prio=10 tID=0x08780c00 nID=0x32ee runnable [0x6fdcc000] java.lang.Thread.State: RUNNABLE at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:943) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) at java.lang.Thread.run(Thread.java:662) "Low Memory Detector" daemon prio=10 tID=0x0874dc00 nID=0x32ec runnable [0x00000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread1" daemon prio=10 tID=0x0874c000 nID=0x32eb waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" daemon prio=10 tID=0x0874a000 nID=0x32ea waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "Signal dispatcher" daemon prio=10 tID=0x08748800 nID=0x32e9 waiting on condition [0x00000000] java.lang.Thread.State: RUNNABLE "Finalizer" daemon prio=10 tID=0x0873a000 nID=0x32e8 in Object.wait() [0x70360000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x9e8f1150> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118) - locked <0x9e8f1150> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159) "Reference Handler" daemon prio=10 tID=0x08735400 nID=0x32e7 in Object.wait() [0x703b1000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x9e8f1050> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:485) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116) - locked <0x9e8f1050> (a java.lang.ref.Reference$Lock) "main" prio=10 tID=0x086b5c00 nID=0x32e3 waiting on condition [0xb6927000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x9e958998> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2025) at java.util.concurrent.ThreadPoolExecutor.awaitTermination(ThreadPoolExecutor.java:1253) at main.Main.<init>(Main.java:19) at main.Main.main(Main.java:10) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58) "VM Thread" prio=10 tID=0x08731800 nID=0x32e6 runnable "GC task thread#0 (ParallelGC)" prio=10 tID=0x086bd000 nID=0x32e4 runnable "GC task thread#1 (ParallelGC)" prio=10 tID=0x086be400 nID=0x32e5 runnable "VM Periodic Task Thread" prio=10 tID=0x0874fc00 nID=0x32ed waiting on condition JNI global references: 931 Heap PSYoungGen total 18752K,used 645K [0x9e8f0000,0x9fdd0000,0xb3790000) eden space 16128K,4% used [0x9e8f0000,0x9e991510,0x9f8b0000) from space 2624K,0% used [0x9fb40000,0x9fb40000,0x9fdd0000) to space 2624K,0% used [0x9f8b0000,0x9f8b0000,0x9fb40000) PSoldGen total 42880K,used 0K [0x74b90000,0x77570000,0x9e8f0000) object space 42880K,0% used [0x74b90000,0x74b90000,0x77570000) PSPermGen total 16384K,used 2216K [0x70b90000,0x71b90000,0x74b90000) object space 16384K,13% used [0x70b90000,0x70dba198,0x71b90000)

是否只有一个Python解释器执行多个并发脚本?

在windows 8.1中,线程可能的最大线程数是多less?

如何增加数字海洋液滴中的并发请求?

一个node.Js集群在64位Wintel PC上产生多less个subprocess?

无法用文件描述符locking文件

实际上是在等待。 ThreadPoolExecutor似乎没有退出逻辑,直到所有任务完成( 请注意 ,只有当您shutdown()时才会发生,否则会正确挂起线程)。

它正在不断地检查一个任务是否准备好执行,如果它不会再次尝试,直到任务被调度的时间已经过去。

关闭一个预定的线程池是一种权衡(这种交换是由实现强加的)。 这是繁忙的旋转,直到任务准备好安排或shutdownNow现在不执行队列任务。 但是,您可以将Runnable的列表返回并自行执行它们。

这是一个特定于平台的问题。 当我在我的机器上运行测试程序时,根据我的机器的cpu使用情况监控,在10秒关机期间,cpu使用率大约为零。

$ java -version java version "1.7.0_03" Java(TM) SE Runtime Environment (build 1.7.0_03-b04) Java HotSpot(TM) ClIEnt VM (build 22.1-b02,mixed mode,sharing)

我粗略搜索了Java BUGs数据库,没有发现任何相关信息。

看一下你可以在网上找到的不同版本的源代码(Google),很明显getTask方法和朋友们在(早期的)Java 1.6和(现在的)Java 1.7之间做了很多工作。

我建议您尝试将您的JVM升级到最新的Java 1.6或Java 1.7。 或者至少试试这个测试程序。 (或者只是和它一起生活,这不是一个表演的障碍……)

仅供参考, 本页包含有关如何在Ubuntu上安装各种版本的Java的说明。

一个选项(对于Java 7)是使用“duinsoft”安装程序,该安装程序是从Oracle站点抽取安装程序的脚本。 他们甚至已经建立了一个deb库来托管安装程序。

另一个选择是安装11.10版本的openjdk-7-jdk或openjdk-7-jre软件包。

而当你在这个区域时,不要忘记在这个RFE上投票, 为Java 7提供Debian软件包/安装程序。

据记载,这个混乱主要是由于Oracle 撤销OEM重新分配许可的结果,这意味着“sun-java-6”软件包必须被撤销。 当然,这也是Oracle不提供DEB的“小问题”。

总结

以上是内存溢出为你收集整理的为什么ScheduledExecutorService.shutdown()使用100%的CPU?全部内容,希望文章能够帮你解决为什么ScheduledExecutorService.shutdown()使用100%的CPU?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1157355.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存