1。ps -ef | grep java
2。jstack -l & lt; pid>比;111.txt
dump 文件里,值得关注的线程状态有:
下面我们先从第一个例子开始分析,然后再列出不同线程状态的含义以及注意事项,最后再补充两个实例。
示范一:
实例如下:
(a org.apache.log4j.Logger)
1)线程状态是Blocked,阻塞状态。说明线程等待资源超时!
2)“”指,线程在等待给这个 0x00000000acf4d0c0 地址上锁(英文可描述为:trying to obtain 0x00000000acf4d0c0 lock)。
3)在 dump 日志里查找字符串 0x00000000acf4d0c0,发现。如果能在日志里找到谁获得了这个锁(如locked < 0x00000000acf4d0c0 >),就可以顺藤摸瓜了。
4)“”说明此线程通过 synchronized(obj) {……} 申请进入了临界区,从而进入了下图1中的“Entry Set”队列,但该 obj 对应的 monitor 被其他线程拥有,所以本线程在 Entry Set 队列中等待。
5)第一行里,是 Thread Name 。tid指Java Thread id。nid指native线程的id。prio是线程优先级。是线程栈起始地址。
Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁。每一个对象都有,也仅有一个 monitor。从下图1中可以看出,每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。在 “Entry Set”中等待的线程状态是 “Waiting for monitor entry”,而在 “Wait Set”中等待的线程状态是 “in Object.wait()”。
示范二:
实例如下:
[0x00007fd4f1a59000]
(a java.util.concurrent.SynchronousQueue$TransferStack)
1)“TIMED_WAITING (parking)”中的 timed_waiting 指等待状态,但这里指定了时间,到达指定的时间后自动退出等待状态;parking指线程处于挂起中。
2)“waiting on condition”需要与堆栈中的“”结合来看。首先,本线程肯定是在等待某个条件的发生,来把自己唤醒。其次,SynchronousQueue 并不是一个队列,只是线程之间移交信息的机制,当我们把一个元素放入到 SynchronousQueue 中时必须有另一个线程正在等待接受移交的任务,因此这就是本线程在等待的条件。
3)别的就看不出来了。
示范三:in Obejct.wait()
实例如下:
[0x00007f34f4bd0000]
1)“TIMED_WAITING (on object monitor)”,对于本例而言,是因为本线程调用了 java.lang.Object.等待(长超时)而进入等待状态。
2)“等设置”中等待的线程状态就是“<强> Object.wait拷贝()强>,“。当线程获得了监视器,进入了临界区之后,如果发现线程继续运行的条件没有满足,它则调用对象(一般就是被同步的对象)的等待()方法,放弃了监视器,进入“等设置”队列。只有当别的线程在该对象上调用了通知()或者notifyAll(),“等待”队列中线程才得到机会去竞争,但是只有一个线程获得对象的监视器,恢复到运行态只
3) RMI RenewClean是DGCClient的一部分.DGC 指的是分布式GC,即分布式垃圾回收。
4)请注意,是先,<强>锁定& lt; 0 x00000000aa672478> >强,后,<强>等待& lt; 0 x00000000aa672478> >强,之所以先锁再等同一个对象,请看下面它的代码实现:
静态私有类,锁{};
私人锁锁=new锁();
公共Reference<?扩展T>删除(长超时)
{
,同步才能(锁){
,,,,,Reference<?, T>,,=, reallyPoll ();
,,,,,(,!=,),,,
,,,,,(,),{
,,,,,.wait才能();
,,,,,,,=,reallyPoll ();