我已经对生产中部署的应用程序进行了线程转储,该应用程序使用 logback。我不是分析线程转储的专家,但是,我需要这样做。我正在学习,也看了一些网上的文章。下面是真实的线程转储:"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)正如我所看到的,大多数线程都处于 WAITING 状态。但我怎么知道他们到底在等什么?这些所有线程是否都试图“等待”“某事”?我确实阅读了一些在线材料,但是当看到真正的线程转储时,对于如何采取步骤来理解这些线程到底试图做什么以及它们在等待什么,这对我来说没有任何意义,被封锁等谁能帮我理解这一点吗?
3 回答
慕斯王
TA贡献1864条经验 获得超2个赞
据我分析线程转储,当您使用 Spring 等框架或其他库(如您在此处使用的 Logback)时。他们根据您的配置创建线程池。例如,您可以在 applicationcontext.xml 或任何基于 java 的配置类中找到此类配置。因此,它的作用是,它将在应用程序启动或第一次初始化调用时创建那么多线程。如果有任何任务到来,那么框架将从池中选择一个线程并分配给它。任务完成后,线程将回到池中,此时线程状态将是WAITING(正在停车)。这并不意味着它被任何线程阻塞。如果您的服务器有足够的能力处理此类池,则不会导致任何性能问题。他们只是坐在理想的位置,因为他们没有任何任务要做。
三国纷争
TA贡献1804条经验 获得超7个赞
根据上面的堆栈跟踪,有以下推论
有一个队列Q。
N 个作业(可运行)被添加到队列中。
这些作业将从队列中取出并由 ThreadPoolExecutors 中的线程执行(可以缓存/动态)。
假设,我们有一个只有两个线程(固定大小)的线程池执行器,并且您只向队列提交了一个作业。(作业1)
Thread1从队列中取出job1并执行。一旦执行结束,就会进入WAITING状态,因为队列中没有元素。它没有工作要做。堆栈跟踪上存在等待线程并不意味着它们是有害的。
潇湘沐
TA贡献1816条经验 获得超6个赞
您可能要做的第一件事是搜索 Runnable 线程及其已锁定的同步器。可运行线程如果长时间挂起,则很有可能正在执行 IO 或 DB 操作。以 30 秒左右的间隔进行后续线程转储并进行比较研究。
添加回答
举报
0/150
提交
取消