等待在sun.misc.Unsafe.park(本地方法)

我的应用程序之一挂在负载下运行的一段时间,有没有人知道什么可能导致这样的输出在jstack中:

"scheduler-5" prio=10 tid=0x00007f49481d0000 nid=0x2061 waiting on condition [0x00007f494e8d0000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000006ee117310> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1085) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:807) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1043) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1103) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722) 

挂起时,我在jstack输出中看到了很多。

我大量使用Spring @Async&maps,同步映射&ehcache。

有趣的是,这只发生在一个应用程序实例。 另外两个人跑得很好。 还有什么我可以调查,以获得更多的细节在这种情况下?

我发现这个posthttps://stackoverflow.com/questions/23992787/parking-to-wait-for-0xd8cf0070-a-java-util-concurrent-locks-abstractqueueds,但它不是非常有用的在我的情况。

unsafe.park与thread.wait几乎相同,除了它使用特定于体系结构的代码(因此它是“不安全”的原因)。 不安全的是不公开的,但在内部的Java库中使用,其中架构特定的代码将提供显着的优化效益。 它被用于线程池。

所以,要回答你的问题,所有的线程正在等待的东西,它不是真正使用任何CPU。 考虑到你的原始堆栈跟踪显示你正在使用一个锁,我会假设你的情况正在发生死锁。

是的,我知道你现在几乎可以肯定已经解决了这个问题。 然而,如果有人使用sun.misc.unsafe.park,那么你就是最好的结果之一。 我回答这个问题可能会帮助其他人试图了解这种方法似乎是使用他们所有的CPU。

从堆栈跟踪很明显,ThreadPoolExecutor> Worker线程启动,并且它正在等待BlockingQueue(DelayedWorkQueue)上的任务可用来select任务并执行。因此,只要获得一个线程,该线程将处于WAIT状态SIGNAL从发布者线程。

我有一个类似的问题,并按照以前的答案(谢谢!),我能够search并find如何正确处理ThreadPoolExecutor终止。

在我的情况下,这只是修复我的渐进增加类似封锁的线程:

  • 我在我的finally子句中使用了ExecutorService::awaitTermination(x, TimeUnit)ExecutorService::shutdownNow() (如果需要的话)。
  • 有关信息,我已经使用以下命令来检测线程数和列表locking的线程:

    ps -u javaAppuser -L | wc -l

    jcmd`ps -C java -o pid =`Thread.print >> threadPrintDayA.log

    jcmd`ps -C java -o pid =`Thread.print >> threadPrintDayAPlusOne.log

    cat threadPrint * .log | grep“pool-”| wc -l