首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ThreadDump:如何查看等待状态/或任何其他状态?

ThreadDump:如何查看等待状态/或任何其他状态?
EN

Stack Overflow用户
提问于 2019-09-10 12:23:16
回答 3查看 3.2K关注 0票数 2

我已经将我的应用程序的线程转储部署到使用logback的生产环境中。我不是分析线程转储的专家,但是我必须这样做。我正在学习它,并且已经阅读了一些在线文章。

下面是真实的线程转储:

代码语言:javascript
复制
"logback-8" #136 daemon prio=5 os_prio=0 tid=0x00007f3588001000 nid=0x13a waiting on condition [0x00007f35f8e7b000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000068d740338> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        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)

"logback-7" #135 daemon prio=5 os_prio=0 tid=0x00007f356c030800 nid=0x139 waiting on condition [0x00007f35f8d7a000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000068d740338> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        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)

"logback-6" #134 daemon prio=5 os_prio=0 tid=0x00007f357c018000 nid=0x138 waiting on condition [0x00007f3568ef0000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000068d740338> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        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)

"logback-5" #133 daemon prio=5 os_prio=0 tid=0x00007f36b8003800 nid=0x137 waiting on condition [0x00007f35f9380000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000068d740338> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        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)

正如我所看到的,这些线程中的大多数都处于等待状态。

但是我怎么知道他们到底在等什么呢?这些线程都在试图“等待”“某些东西”吗?

我确实阅读了一些在线材料,但当我看到一个真正的线程转储时,我不明白如何采取步骤来理解这些线程到底想做什么,以及它们在等待什么,被阻塞等等。

有没有人能帮我理解一下?

EN

回答 3

Stack Overflow用户

发布于 2019-09-10 12:58:45

就我所分析的线程转储而言,当你使用像Spring这样的框架,或者像你在这里使用的其他库一样,Logback。它们会根据你的配置创建线程池。例如,您可以在applicationcontext.xml或任何基于java的配置类中找到这样的配置。因此,它所做的是,它将在应用程序启动或第一次初始化调用时创建那么多线程。如果有任何任务到来,框架将从池中挑选一个线程并分配它。任务完成后,线程将返回到池中,此时线程状态将类似于等待(驻留)。这并不意味着它被任何线程阻塞。如果您的服务器有足够的能力处理这样的池,那么它不会引起任何性能问题。他们只是坐得很好,因为他们没有任何任务要做。

你可以在this上找到更多信息,如果你想查看线程转储的可视化分析方法,那么你可以使用this。我发现这个网站很有帮助。只需上传您的转储file.It就会告诉您线程转储需要知道的所有事情。

票数 1
EN

Stack Overflow用户

发布于 2019-09-21 17:35:51

基于上面的堆栈跟踪,以下是推论

这些作业将从队列中取出,并由ThreadPoolExecutors中的线程执行(可以是Q.

  • N )(可以是cached/Dynamic).

)。

  • of job(Runnables)
  • 这些作业将从队列中取出并由ThreadPoolExecutors中的线程执行

让我们假设,我们有一个只有两个线程(固定大小)的线程池执行器,并且您只向队列提交了一个作业。(Job1)

Thread1从队列中获取job1并执行。一旦执行结束,它就进入等待状态,因为队列中没有元素。它没有工作要做。堆栈跟踪中存在等待线程并不意味着它们是有害的。

票数 1
EN

Stack Overflow用户

发布于 2019-09-22 20:19:13

您可能要做的第一件事是搜索Runnable线程和它锁定的同步器。Runnable线程如果挂起了很长时间,那么它很有可能正在执行IO或DB操作。以30秒左右的间隔进行后续线程转储,并进行比较研究。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57864026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档