码迷,mamicode.com
首页 > Web开发 > 详细

jstack 使用

时间:2016-07-11 16:53:05      阅读:318      评论:0      收藏:0      [点我收藏+]

标签:

dump 文件里,值得关注的线程状态有:
  1. 死锁,Deadlock(重点关注) 
  2. 执行中,Runnable   
  3. 等待资源,Waiting on condition(重点关注) 
  4. 等待获取监视器,Waiting on monitor entry(重点关注)
  5. 暂停,Suspended
  6. 对象等待中,Object.wait() 或 TIMED_WAITING
  7. 阻塞,Blocked(重点关注)  
  8. 停止,Parked

Runnable:不解释

Wait on condition:该状态出现在线程等待某个条件的发生。具体是什么原因,可以结合 stacktrace来分析。最常见的情况是线程在等待网络的读写。如果网络数据没准备好,线程就等待在那里。另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。

Waiting for monitor entry 和 in Object.wait():这两种情况在多线程的情况下经常出现。Java是通过Monitor来实现线程互斥和协作(有些把Monitor直译成锁,我认为不妥,不是还有Lock嘛)。具体Monitor的深入理解见 http://www.cnblogs.com/tomsheep/archive/2010/06/09/1754419.html

但是可以理解成Monitor是一个对象或者class所拥有的锁,每个对象和class有且仅有一个。见下图.


技术分享

每个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程都是 “Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。

在 “ Entry Set”里面的线程都等待拿到Monitor,拿到了线程就成为了Runnable线程,否则就会一直处于处于 “waiting for monitor entry”。一段代码作为例子

public class MyThread implements Runnable{    
  
     public void run() {    
         synchronized(this) {    
              for (int i = 0; i < 1; i--) {    
                   System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);    
              }    
         }    
    }    
    public static void main(String[] args) {    
        MyThread t1 = new MyThread();    
         Thread ta = new Thread(t1, "A");    
         Thread tb = new Thread(t1, "B");    
         ta.start();    
         tb.start();    
    }   
  
}  

大家一看就知道,B线程肯定是“千年老二“,永远拿不到Monitor了。

对应的stack:

"B" prio=10 tid=0x0969a000 nid=0x11d6 waiting for monitor entry [0x8bb22000]  
   java.lang.Thread.State: BLOCKED (on object monitor)  
    at org.marshal.MyThread.run(MyThread.java:7)  
    - waiting to lock <0x94757078> (a org.marshal.MyThread)  
    at java.lang.Thread.run(Thread.java:636)  
  
"A" prio=10 tid=0x09698800 nid=0x11d5 runnable [0x8bb73000]  
   java.lang.Thread.State: RUNNABLE  
    at java.io.FileOutputStream.writeBytes(Native Method)  
    at java.io.FileOutputStream.write(FileOutputStream.java:297)  
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)  
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)  
    - locked <0x947571b0> (a java.io.BufferedOutputStream)  
    at java.io.PrintStream.write(PrintStream.java:449)  
    - locked <0x94757190> (a java.io.PrintStream)  
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:220)  
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:290)  
    at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:103)  
    - locked <0x947572a0> (a java.io.OutputStreamWriter)  
    at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)  
    at java.io.PrintStream.write(PrintStream.java:494)  
    - locked <0x94757190> (a java.io.PrintStream)  
    at java.io.PrintStream.print(PrintStream.java:636)  
    at java.io.PrintStream.println(PrintStream.java:773)  
    - locked <0x94757190> (a java.io.PrintStream)  
    at org.marshal.MyThread.run(MyThread.java:8)  
    - locked <0x94757078> (a org.marshal.MyThread)  
    at java.lang.Thread.run(Thread.java:636)  

 <0x94757078> 就是两个线程争夺的Monitor

 

在 “Wait Set”里面的线程都如饥似渴地等待拿到Monitor。他们是怎么进入到“Wait Set”的呢?当一个线程拿到了Monitor,但是在其他资源没有到位的情况下,调用同步锁对象(一般是synchronized()内的对象)的 wait() 方法,放弃了 Monitor,它就进入到了 “Wait Set”队列。只有当其他线程通过notify() 或者 notifyAll(),释放了同步锁后,这个线程才会有机会重新去竞争Monitor。在stack中,它表现的状态是in Object.wait()。修改上面的代码public class WaitThread implements Runnable{

public void run() {    
      synchronized(this) {   
        try {  
        this.wait();  
    } catch (InterruptedException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    }              
      }    
 }    
 public static void main(String[] args) {    
   WaitThread t1 = new WaitThread();    
      Thread ta = new Thread(t1, "A");    
      Thread tb = new Thread(t1, "B");    
      ta.start();    
      tb.start();            
 }   

 对应的stack:

"B" prio=10 tid=0x08173000 nid=0x1304 in Object.wait() [0x8baf2000]  
   java.lang.Thread.State: WAITING (on object monitor)  
    at java.lang.Object.wait(Native Method)  
    - waiting on <0xa9cb50e0> (a org.marshal.WaitThread)  
    at java.lang.Object.wait(Object.java:502)  
    at org.marshal.WaitThread.run(WaitThread.java:8)  
    - locked <0xa9cb50e0> (a org.marshal.WaitThread)  
    at java.lang.Thread.run(Thread.java:636)  
  
"A" prio=10 tid=0x08171c00 nid=0x1303 in Object.wait() [0x8bb43000]  
   java.lang.Thread.State: WAITING (on object monitor)  
    at java.lang.Object.wait(Native Method)  
    - waiting on <0xa9cb50e0> (a org.marshal.WaitThread)  
    at java.lang.Object.wait(Object.java:502)  
    at org.marshal.WaitThread.run(WaitThread.java:8)  
    - locked <0xa9cb50e0> (a org.marshal.WaitThread)  
    at java.lang.Thread.run(Thread.java:636)  

A和B线程都进入了”wait set“。B线程也拿到过这个Monitor,因为A线程释放过了,这也验证上面的话,他们都在等待得而复失的<0xa9cb50e0>

 

 

 

转自  http://go-on.iteye.com/blog/1673894

jstack 使用

标签:

原文地址:http://www.cnblogs.com/SamuelSun/p/5660574.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!