在到处java线程栈的时候,会看到线程栈第一行最后都有一个状态说明,下面就说一下这几种状态是什么情况下出现的,理解java线程栈对于分析问题非常有帮助;

/**
  * 一. waiting for monitor entry
  * 
  * BLOCKED (on object monitor)
  * 等待进入synchronized临界区
  * 
  * 二. in Object.wait()
  * 1. TIMED_WAITING (on object monitor)
  * 执行了java.lang.Object.wait(timeout)(Native Method)方法
  * 
  * 2. WAITING (on object monitor)
  * 执行了java.lang.Object.wait(Native Method)方法
  * 
  * 
  * 三. waiting on condition
  * 
  * 1.TIMED_WAITING (sleeping)
  * java.lang.Thread.sleep(Native Method)
  * 
  * 2.TIMED_WAITING (parking)
  * sun.misc.UNSAFE.park(false, nanos);
  * java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
  * 
  * 3.WAITING (parking)
  * sun.misc.UNSAFE.park(false, 0L);
  * java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
  * 
  * 4. RUNNABLE 特殊情况
  * 很多本地线程处于此状态
  * 
  * 四. runnable
  * 
  * 1.RUNNABLE
  * 正在jvm内运行的线程
  * 
  * 2.RUNNABLE 特殊情况
  * 正在执行本地方法的线程,jvm获取不到其状态,可能是阻塞状态;
  * 
  * @author zqz
  *
  */下面相机

waiting on condition 



这种状态三种子状态:

 一、TIMED_WAITING (sleeping)

当调用了Thread.sleep()方法时会进入这种状态,线程栈如下:

java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)

需要注意的是,如果线程持有锁,则不会释放锁; 

 二、TIMED_WAITING (parking)

    sun.misc.UNSAFE.park(false, nanos);


     java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)

 


 三、WAITING (parking)

 sun.misc.UNSAFE.park(false, 0L);


 java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)


有以下几种情况会进入WAITING(parking)状态

  •  LockSupport.park() 

java.lang.Thread.State: WAITING (parking)


at sun.misc.Unsafe.park(Native Method)


at java.util.concurrent.locks.LockSupport.park(LockSupport.java:304)

直接在我们应用中调用了LockSupport.park()方法,没有参数,将当前线程阻塞;

  • LockSupport.park(Object)

   调用该方法有以下三种场景

1)ReentrantLock.lock()方法

java.lang.Thread.State: WAITING (parking)


at sun.misc.Unsafe.park(Native Method)


- parking to wait for  <0x00000000d62762c0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)


at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)


at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)


at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)


at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)


at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)


at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)



这里是调用了可重入锁的lock方法,可重入锁最终是调用了LockSuport.park(Object)方法将线程阻塞的,与无参的LockSupport.Park()方法的调用栈是不一样的;

2)RetreenLock.newCondition().await()

 java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  <0x00000000d6276400> (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)

调用了RetreenLock.newCondition().await()方法,最终调用的也是LockSupport.park(Object)方法;

3)在应用中直接调用Locksupport.park(Object)方法

调用栈参考上面两个,这里就不列出来了


上面三种是一样的,列出前两种的目的是为了让大家清楚,当调用栈像给出的那样时,我们调用了哪些java哪些内置的方法间接调用的LockeSupprot.park(Object)方法;





  四、 runnable

特殊情况,这种状态不一致的情况也会出现,处于此状态的线程正在执行本地方法,应该算是jvm中的一个bug;




waiting for monitor entry

这种状态的线程只有一种子状态:BLOCKED (on object monitor)

 java.lang.Thread.State: BLOCKED (on object monitor)


at com.zqz.test.threadstate.ThreadStateTest$Monitor_EntrySet.Monitor_EntrySet_run(ThreadStateTest.java:137)


- waiting to lock <0x00000000d6274fa0> (a java.lang.Boolean)

线程进入synchronized同步块之前,因为已经有其它线程进入同步块了,所以当先线程被阻塞在EntrySet队列中等待进入synchronized代码块;



in Object.wait()

这种状态的线程有两种子状态:

 1. TIMED_WAITING (on object monitor)

 执行了java.lang.Object.wait(timeout)(Native Method)方法,带有是时间

  2. WAITING (on object monitor)

 执行了java.lang.Object.wait(Native Method)方法


 java.lang.Thread.State: WAITING (on object monitor)


at java.lang.Object.wait(Native Method)


- waiting on <0x00000000d6274fa0> (a java.lang.Boolean)


at java.lang.Object.wait(Object.java:502)


at com.zqz.test.threadstate.ThreadStateTest$Monitor_WaitSet.Monitor_WaitSet_run(ThreadStateTest.java:157)


- locked <0x00000000d6274fa0> (a java.lang.Boolean)



处于这种状态的线程,线程栈首先会有一个locked动作,说明其应进入到了synchronized代码块,在代码快中由于某些条件不满足,无法继续执行,又做了Object.Wait()操作释放锁进入等待状态;




runnable




 java.lang.Thread.State: RUNNABLE

java线程正在运行,需要注意的是这种线程如果在执行本地方法,而本地方法阻塞了线程,虽然线程处于阻塞状态,但是java线程获取不到本地方法执行的状态,这时仍然显示runnable;





  • Thread.sleep()

java.lang.Thread.State: TIMED_WAITING (sleeping)


at java.lang.Thread.sleep(Native Method)



线程执行了sleep方法,需要注意的是,如果线程持有锁,则不会释放锁;



锁与线程栈的关系

Synchronized锁

来看下0x00000007d616a0c8锁的执行过程:

一、线程WaitSet--locked--waiting on--in Object.wait()1 先运行:


"WaitSet--locked--waiting on--in Object.wait()1" prio=6 tid=0x000000000d9fb800 nid=0x2e3c in Object.wait() [0x000000000e76f000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x00000007d616a0c8> (a java.lang.Boolean)
	at java.lang.Object.wait(Object.java:503)
	at com.zqz.test.threadstate.ThreadStateTest$Monitor_WaitSet.Monitor_WaitSet_run(ThreadStateTest.java:1525)
	- locked <0x00000007d616a0c8> (a java.lang.Boolean)
	at com.zqz.test.threadstate.ThreadStateTest$Monitor_WaitSet.run(ThreadStateTest.java:1517)

   Locked ownable synchronizers:
	- None





这个线程:

1. 执行- locked <0x00000007d616a0c8> (a java.lang.Boolean)  持有了锁;

2. 执行- waiting on <0x00000007d616a0c8> (a java.lang.Boolean)  执行了Object.wait()释放了锁,并进入到wait 队列;


二、线程”locked--sleeping--wait on Condition1“开始执行:


"locked--sleeping--wait on Condition1" prio=6 tid=0x000000000d9fc000 nid=0x142c waiting on condition [0x000000000e8bf000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at com.zqz.test.threadstate.ThreadStateTest$LockedSleeping.LockedSleeping_run(ThreadStateTest.java:1565)
	- locked <0x00000007d616a0d8> (a java.lang.Object)
	- locked <0x00000007d616a0c8> (a java.lang.Boolean)
	at com.zqz.test.threadstate.ThreadStateTest$LockedSleeping.run(ThreadStateTest.java:1547)

   Locked ownable synchronizers:
	- None



这个线程在上面线程释放锁后,它执行 - locked <0x00000007d616a0c8> (a java.lang.Boolean)  持有了锁;



三、线程“EntrySet--waiting to lock---Waiting for monitor entry2”开始执行

"EntrySet--waiting to lock---Waiting for monitor entry2" prio=6 tid=0x000000000da03000 nid=0x383c waiting for monitor entry [0x000000000ebcf000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at com.zqz.test.threadstate.ThreadStateTest$Monitor_EntrySet.Monitor_EntrySet_run(ThreadStateTest.java:1505)
	- waiting to lock <0x00000007d616a0c8> (a java.lang.Boolean)
	at com.zqz.test.threadstate.ThreadStateTest$Monitor_EntrySet.run(ThreadStateTest.java:1492)

   Locked ownable synchronizers:
	- None

这个线程执行后发现锁已经被别的线程持有了,所以执行- waiting to lock <0x00000007d616a0c8> (a java.lang.Boolean) 进入到monitor entry队列,等待竞争锁;



ReentrantLock


"RTlock has Lock1" prio=6 tid=0x000000000da2c800 nid=0x3830 waiting on condition [0x000000000ed0f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at com.zqz.test.threadstate.ThreadStateTest$RTlockLocked.run(ThreadStateTest.java:1445)

   Locked ownable synchronizers:
	- <0x00000007d616a378> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)



Locked ownable synchronizers: 代表当前线程持有了0x00000007d616a378锁

"RTlock wait Lock2" prio=6 tid=0x000000000da34000 nid=0xacc waiting on condition [0x000000000ee9f000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000007d616a378> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:834)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:867)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
	at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:214)
	at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
	at com.zqz.test.threadstate.ThreadStateTest$RTlockWaitLocke.run(ThreadStateTest.java:1470)

   Locked ownable synchronizers:
	- None

- parking to wait for  <0x00000007d616a378> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

代表当前线程正在等待0x00000007d616a378锁


LockSupport.park()锁


"LockSupportPark2--park1" prio=6 tid=0x000000000d9f6800 nid=0x2a44 waiting on condition [0x000000000e66f000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x00000007d616e988> (a com.zqz.test.threadstate.ThreadStateTest$LockSupportPark2)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
	at com.zqz.test.threadstate.ThreadStateTest$LockSupportPark2.park(ThreadStateTest.java:1610)
	at com.zqz.test.threadstate.ThreadStateTest$LockSupportPark2.parkMethod(ThreadStateTest.java:1605)
	at com.zqz.test.threadstate.ThreadStateTest$LockSupportPark2.run(ThreadStateTest.java:1602)

   Locked ownable synchronizers:
	- None

代表它执行LockSupport.park把自己给阻塞了,需要另外一个线程unpark这个线程才能继续执行;这种情况并没有其它线程持有锁