正如我们在评论中确定的那样,消耗CPU的线程在以下堆栈中很忙:
"pool-9-thread-1" #49 prio=5 os_prio=0 tid=0x00007ffd508e8000 nid=0x3a0c runnable [0x00007ffd188b6000]
java.lang.Thread.State: RUNNABLE
at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.poll(ScheduledThreadPoolExecutor.java:809)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1066)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
我设法通过创建一个ScheduledThreadPoolExecutor,配置它来允许核心线程超时,并以很短的延迟安排大量的重复任务来重现类似的行为.它在我的机器上产生了大量的CPU,并且jstack输出是相似的(有时候更深入于poll方法).此代码重现:
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
executor.setKeepAliveTime(1, TimeUnit.MINUTES);
executor.allowCoreThreadTimeOut(true);
for (long i = 0; i < 1000; i++) {
executor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
}
}, 0, 1, TimeUnit.NANOSECONDS);
}
现在我们只需要确定哪个代码设置了一个破坏的ScheduledThreadPoolExecutor.我通过RabbitMQ和Netty源代码搜索,而没有发现任何东西.你可以在自己的代码中做一些事情吗?
编辑:如注释中所述,根本原因是用0初始化的ScheduledThreadPoolExecutor,这显然可能会导致一些平台的CPU旋转.这是在OP的代码中完成的.