转载:http://itindex.net/detail/43158-tda-%E5%B7%A5%E5%85%B7-java
 
使用 TDA 工具,看到大量 Java Thread State 的第一反应是:

1,线程状态为“waiting for monitor entry”:
意味着它  在等待进入一个临界区 ,所以它在”Entry Set“队列中等待。
此时线程状态一般都是 Blocked:
  • java.lang.Thread.State:  BLOCKED (on object monitor)
 
 
2,线程状态为“waiting on condition”:
说明它 在等待另一个条件的发生,来把自己唤醒,或者干脆它是调用了 sleep(N)。
此时线程状态大致为以下几种:
  • java.lang.Thread.State:  WAITING (parking):一直等那个条件发生;
  • java.lang.Thread.State:  TIMED_WAITING (parking或sleeping):定时的,那个条件不到来,也将定时唤醒自己。

 
3,如果大量线程在 “waiting for monitor entry”:
可能是一个全局锁阻塞住了大量线程。
如果短时间内打印的 thread dump 文件反映,随着时间流逝,waiting for monitor entry 的线程越来越多,没有减少的趋势,可能意味着 某些线程在临界区里呆的时间太长了,以至于越来越多新线程迟迟无法进入临界区
 

 
 
4,如果大量线程在  waiting on condition ”:
可能是它们又跑去获取第三方资源, 尤其是第三方网络资源,迟迟获取不到Response,导致大量线程进入等待状态。
所以如果你发现有大量的线程都处在 Wait on condition,从线程堆栈看,正等待网络读写 ,这可能是一个网络瓶颈的征兆,因为网络阻塞导致线程无法执行。
 

线程状态为“in Object.wait()”:
说明它 获得了监视器之后,又调用了 java.lang.Object.wait() 方法
每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。在 “Entry Set”中等待的线程状态是 “Waiting for monitor entry”,而在 “Wait Set”中等待的线程状态是 “in Object.wait()”。
当线程获得了 Monitor,如果发现线程继续运行的条件没有满足,它则调用对象(一般就是被 synchronized 的对象)的 wait() 方法,放弃了 Monitor,进入 “Wait Set”队列。
此时线程状态大致为以下几种:
  • java.lang.Thread.State:  TIMED_WAITING (on object monitor);
  • java.lang.Thread.State:  WAITING (on object monitor);
一般都是RMI相关线程(RMI RenewClean、 GC Daemon、RMI Reaper),GC线程(Finalizer),引用对象垃圾回收线程(Reference Handler)等系统线程处于这种状态。
 
 
图1 A Java Monitor
 
示范一:
下面这个线程在等待这个锁  0x00000000fe7e3b50,等待进入临界区:
"RMI TCP Connection(64896)-172.16.52.118" daemon prio=10 tid=0x00000000405a6000 nid=0x68fe waiting for monitor entry [0x00007f2be65a3000]
   java.lang.Thread.State: BLOCKED (on object monitor)
at com.xyz.goods.service.impl.GoodsServiceImpl. findChanellGoodsCountWithCache(GoodsServiceImpl.java:1734)
-  waiting to lock <0x00000000fe7e3b50> (a java.lang.String)
那么谁持有这个锁呢?
是另一个先调用了 findChanellGoodsCountWithCache 函数的线程:
"RMI TCP Connection(64878)-172.16.52.117" daemon prio=10 tid=0x0000000040822000 nid=0x6841 runnable [0x00007f2be76b3000]
   java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
- locked <0x00000000af4ed638> (a java.io.BufferedInputStream)
at org.bson.io.Bits.readFully(Bits.java:35)
at org.bson.io.Bits.readFully(Bits.java:28)
at com.mongodb.Response.<init>(Response.java:35)
at com.mongodb.DBPort.go(DBPort.java:110)
- locked <0x00000000af442d48> (a com.mongodb.DBPort)
at com.mongodb.DBPort.go(DBPort.java:75)
- locked <0x00000000af442d48> (a com.mongodb.DBPort)
at com.mongodb.DBPort.call(DBPort.java:65)
at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:202)
at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:296)
at com.mongodb.DB.command(DB.java:152)
at com.mongodb.DBCollection.getCount(DBCollection.java:760)
at com.mongodb.DBCollection.getCount(DBCollection.java:731)
at com.mongodb.DBCollection.count(DBCollection.java:697)
at com.xyz.goods.manager.MongodbManager.count(MongodbManager.java:202)
at com.xyz.goods.service.impl.GoodsServiceImpl.findChanellGoodsCount(GoodsServiceImpl.java:1787)
at com.xyz.goods.service.impl.GoodsServiceImpl. findChanellGoodsCountWithCache(GoodsServiceImpl.java:1739)
-  locked <0x00000000fe7e3b50> (a java.lang.String)
示范二:
等待另一个条件发生来将自己唤醒:
"RMI TCP Connection(idle)" daemon prio=10 tid=0x00007fd50834e800 nid=0x56b2  waiting on condition [0x00007fd4f1a59000]
   java.lang.Thread.State:  TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
-  parking to wait for  <0x00000000acd84de8> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:424)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:323)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:874)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:945)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
at java.lang.Thread.run(Thread.java:662)
1)“ TIMED_WAITING (parking)”中的 timed_waiting 指等待状态,但这里指定了时间,到达指定的时间后自动退出等待状态;parking指线程处于挂起中。
2)“ waiting on condition”需要与堆栈中的“ parking to wait for  <0x00000000acd84de8> (a java.util.concurrent.SynchronousQueue$TransferStack)” 结合来看。首先,本线程肯定是在等待某个条件的发生,来把自己唤醒。其次,SynchronousQueue 并不是一个队列,只是线程之间移交信息的机制,当我们把一个元素放入到 SynchronousQueue 中时必须有另一个线程正在等待接受移交的任务,因此这就是本线程在等待的条件。
 
示范三:
"RMI RenewClean-[172.16.50.182:4888]" daemon prio=10 tid=0x0000000040d2c800 nid=0x97e  in Object.wait() [0x00007f9ccafd0000]
   java.lang.Thread.State:  TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000799b032d8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <0x0000000799b032d8> (a java.lang.ref.ReferenceQueue$Lock)
at sun.rmi.transport.DGCClient$EndpointEntry$RenewCleanThread.run(DGCClient.java:516)
at java.lang.Thread.run(Thread.java:662)
 
参考资源:
1)CUBRID,2012, How to Analyze Java Thread Dumps

在 TDA 工具里看到 Java Thread State 的第一反应是的更多相关文章

  1. 分析Java Thread State

    使用 TDA 工具,看到大量 Java Thread State 的第一反应是: 1,线程状态为“waiting for monitor entry”: 意味着它 在等待进入一个临界区 ,所以它在”E ...

  2. 各种 Java Thread State 分析

    转自:https://www.cnblogs.com/zhengyun_ustc/archive/2013/03/18/tda.html 1,线程状态为“waiting for monitor ent ...

  3. 各种 Java Thread State【转载】

    1,线程状态为“waiting for monitor entry”: 意味着它 在等待进入一个临界区 ,所以它在”Entry Set“队列中等待. 此时线程状态一般都是 Blocked: java. ...

  4. jar包里查找指定的class文件,排查是否存在或重复,工具软件:Java Class Finder

    jar包里查找指定的class文件,排查是否存在或重复,工具软件:Java Class Finder 1,下载工具地址:www.idesksoft.com/classfinder.html,如图: 2 ...

  5. java.lang.Thread.State类详解

    public static enum Thread.Stateextends Enum<Thread.State>线程状态.线程可以处于下列状态之一: 1.NEW 至今尚未启动的线程的状态 ...

  6. “全栈2019”Java多线程第十章:Thread.State线程状态详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  7. 性能分析之-- JAVA Thread Dump 分析综述

    性能分析之-- JAVA Thread Dump 分析综述       一.Thread Dump介绍 1.1什么是Thread Dump? Thread Dump是非常有用的诊断Java应用问题的工 ...

  8. 三、jdk工具之jstack(Java Stack Trace)

    目录 一.jdk工具之jps(JVM Process Status Tools)命令使用 二.jdk命令之javah命令(C Header and Stub File Generator) 三.jdk ...

  9. Java Thread 那些事

    这篇文章被压在草稿箱许久,最近公司内部的技术社区有同学贴出了几篇分享 Java线程的文章,发觉有很多概念没有讲清楚,所以花点时间继续撰写,便有了这篇博文. 本文只聚焦 JVM 层面的线程模型,不考虑和 ...

随机推荐

  1. sublime text光标移入移出括号的快捷键设置

    使用sublime text每次输入完一个函数或者标签,光标一般都是停留在括号中间,要跳出来要使用左右方向键或者end键 这俩键键区比较远,按起来麻烦,可以自己设置快捷键实现跳出的功能. 原来的快捷键 ...

  2. NoSQL 数据库应用

      类型 部分代表 特点 列存储 Hbase Cassandra Hypertable 顾名思义,是按列存储数据的.最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查 ...

  3. 4.Spark Streaming事务处理

    首先,我们必须知道什么是事务及其一致性? 事务应该具有4个属性:原子性.一致性.隔离性.持久性.这四个属性通常称为ACID特性. 原子性(atomicity).一个事务是一个不可分割的工作单位,事务中 ...

  4. vmware漏洞之一——转:利用一个堆溢出漏洞实现VMware虚拟机逃逸

    转:https://zhuanlan.zhihu.com/p/27733895?utm_source=tuicool&utm_medium=referral 小结: vmware通过Backd ...

  5. NIO使用Reactor模式遇到的问题

    关于Reactor模式,不再多做介绍,推荐Doug Lea大神的教程:Java 可扩展的IO 本来在Reactor的构造方法中完成一系列操作是没有问题的: public class Reactor i ...

  6. 编译 Windows 版本的 Unity Mono(2017-03-12 20:59)

    上一篇说了如何编译 Android 下的 mono,这里简要说下编译 windows 版本的 mono,就是 mono.dll,Unity 版本只有一个 mono.dll,官方的 mono,好几个可执 ...

  7. Loj#6433「PKUSC2018」最大前缀和(状态压缩DP)

    题面 Loj 题解 先转化题意,其实这题在乘了\(n!\)以后就变成了全排列中的最大前缀和的和(有点拗口).\(n\leq20\),考虑状压\(DP\) 考虑一个最大前缀和\(\sum\limits_ ...

  8. 线程间操作无效: 从不是创建控件“textBox2”的线程访问它

    如何:对 Windows 窗体控件进行线程安全调用 线程间操作无效: 从不是创建控件的线程访问它的三种方法 如果使用多线程处理来提高 Windows 窗体应用程序的性能,则你必须确保以线程安全的方式调 ...

  9. POJ1704 Georgia and Bob 博弈论 尼姆博弈 阶梯博弈

    http://poj.org/problem?id=1704 我并不知道阶梯博弈是什么玩意儿,但是这道题的所有题解博客都写了这个标签,所以我也写了,百度了一下,大概是一种和这道题类似的能转换为尼姆博弈 ...

  10. [Codeforces-div.1 494B]Obsessive String

    [CF-div.1 B]Obsessive String 题目大意 两个字符串\(S,T\),求划分方案数使得一个集合中两两划分不相交且划分都包含字符串\(T\) 试题分析 kmp先求出那个位置匹配. ...