一条线程堆栈信息大概长成下面这个样子:
RMI TCP Connection(267865)-172.16.5.25" daemon prio=10 tid=0x00007fd508371000 nid=0x55ae waiting for monitor entry [0x00007fd4f8684000]
java.lang.Thread.State: BLOCKED (on object monitor)
at org.apache.log4j.Category.callAppenders(Category.java:201)
- waiting to lock <0x00000000acf4d0c0> (a org.apache.log4j.Logger)
at org.apache.log4j.Category.forcedLog(Category.java:388)
at org.apache.log4j.Category.log(Category.java:853)
at org.apache.commons.logging.impl.Log4JLogger.warn(Log4JLogger.java:234)
at com.tuan.core.common.lang.cache.remote.SpyMemcachedClient.get(SpyMemcachedClient.java:110)
根据上面这个样例,我们来逐个字段看下:
1.prio=10,线程优先级,1~10,10的优先级最高,优先执行。
2.tid线程ID,Thread.getId()方法获取的就是这个ID;
3.nid,操作系统上的原生id。如在linux系统上可以通过ps p PID -L -o pcpu,pid,tid,time,tname,cmd来获得进程ID为PID的线程ID,对应字段TID;获取到这个10进制的TID后,通过printf "%x\n" TID可以转换为堆栈信息中的16进制的nid。
4.waiting for monitor entry说明了当前线程再做什么,英文字面意思理解就可以。样例中这个可以理解为在等待对象监视器,一般就是说被synchoniezed字段锁了对象,正在等待获取这个对象的监视器。其他还有如waiting on condition,等待获取资源;DeadLock,死锁;Object.wait,等待对象等。
5. java.lang.Thread.State: BLOCKED这个说的是当前的线程状态,其他需要关注的状态还有DeadLock,Runnable,Waiting 。如果遇到阻塞,先看阻塞的waiting to lock <0x00000000acf4d0c0>对象,根据对象的ID 0x00000000acf4d0c0找是被哪个线程锁住的,然后再具体分析锁住的线程的堆栈信息,占用锁的线程会有locke<0x00000000acf4d0c0>。