常见的线程状态:
RUNNABLE:正在执行的线程
注意:这里执行是针对jvm来说的,并非真的在cpu上执行,这要看操作系统处理器是否有机会
BLOCKED:阻塞的线程
注意:阻塞的线程一般是拿不到监视器锁(a monitor lock),比如:synchronized block/method,ReentrantLock.lock()
jstack一般显示为:
"Thread-0" prio=6 tid=0x000000000b67f800 nid=0x40d0 waiting on condition [0x000000000da7f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at Test$1.run(Test.java:26)
- locked <0x00000007d5df43f8> (a java.util.HashMap)
"main" prio=6 tid=0x00000000021cf000 nid=0x1870 waiting for monitor entry [0x000000000262f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at Test.test1(Test.java:39)
- waiting to lock <0x00000007d5df43f8> (a java.util.HashMap)
at Test.main(Test.java:7)
分析:
Thread-0:
1、拿到了锁并且没有释放:locked <0x00000007d5df43f8> (a java.util.HashMap)
2、线程调用了sleep方法,java.lang.Thread.State: TIMED_WAITING (sleeping)
main线程:
1、java.lang.Thread.State: BLOCKED (on object monitor):因为锁被Thread-0 占用,拿不到锁( waiting for monitor entry),进入 BLOCKED 状态
2、waiting to lock <0x00000007d5df43f8> (a java.util.HashMap):首先锁的编号是:0x00000007d5df43f8,锁的对象是HashMap (a java.util.HashMap)
总结:
1、这种方式可以轻松分析出来 BLOCKED 的线程是被那个锁阻塞的
2、从代码的输出可以看出:线程Thread-0 持有锁,进入sleep后,不会释放锁,否则main线程的(##############) 会输出
3、echo "obase=10;ibase=16;40D0"|bc ; 输出为:16592,可以定位线程id
java 代码为:
private static void test1() throws Exception { final Mapmap = new HashMap (); new Thread() { @Override public void run() { synchronized (map) { try { System.out.println("***************"); System.out.println("map: " +Long.toHexString(map.hashCode())); System.out.println("map: " +(map)); System.out.println("newThread: " +(Thread.currentThread().getId())); System.out.println("newThread: " +Long.toHexString(Thread.currentThread().getId())); System.out.println("newThread: " +Long.toHexString(Thread.currentThread().hashCode())); Thread.sleep(10000000); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); Thread.sleep(10000); System.out.println("mainThread: " +(Thread.currentThread().getId())); System.out.println("mainThread: " +Long.toHexString(Thread.currentThread().getId())); System.out.println("mainThread: " +Long.toHexString(Thread.currentThread().hashCode())); synchronized (map) { System.out.println("##############"); map.wait(); } int i = 0; while (true) { map.put("value" + i, new User(i)); i++; if (map.size() > 1000000) { map.clear(); } } }
输出:
***************
map: 0
map: {}
newThread: 9
newThread: 9
newThread: 64afb650
mainThread: 1
mainThread: 1
mainThread: 138b9a72
WAITING:等待状态
一般以下三种调用:
Object.wait with no timeout
Thread.join with no timeout
LockSupport.park
jstack一般显示为:
"Thread-0" prio=6 tid=0x000000000d447000 nid=0x31b8 in Object.wait() [0x000000000da8f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007d5df43f8> (a java.util.HashMap)
at java.lang.Object.wait(Object.java:503)
at Test$2.run(Test.java:65)
- locked <0x00000007d5df43f8> (a java.util.HashMap)
"main" prio=6 tid=0x000000000238f000 nid=0x372c in Object.wait() [0x000000000279f000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007d5df43f8> (a java.util.HashMap)
at java.lang.Object.wait(Object.java:503)
at Test.test2(Test.java:78)
- locked <0x00000007d5df43f8> (a java.util.HashMap)
at Test.main(Test.java:7)
分析:
1、Thread-0 和 main 线程 都是因为调用 wait() 方法 进入阻塞的
2、他们都拿到了锁:locked <0x00000007d5df43f8> (a java.util.HashMap)
3、java.lang.Thread.State: WAITING (on object monitor):他们都在等待 对象监视器(on object monitor)的通知
4、从代码的输出可以看出:线程进入wait后,会释放锁,否则(##############) 不会输出
5、0x000000000da8f000,0x000000000279f000 的值的含义为:线程的起始栈地址
java代码:
private static void test2() throws Exception { final Mapmap = new HashMap (); new Thread() { @Override public void run() { synchronized (map) { try { System.out.println("***************"); System.out.println("newThread: " +Long.toHexString(Thread.currentThread().getId())); System.out.println("newThread: " +Long.toHexString(Thread.currentThread().hashCode())); map.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); Thread.sleep(10000); System.out.println("mainThread: " +Long.toHexString(Thread.currentThread().getId())); System.out.println("mainThread: " +Long.toHexString(Thread.currentThread().hashCode())); synchronized (map) { System.out.println("##############"); map.wait(); } int i = 0; while (true) { map.put("value" + i, new User(i)); i++; if (map.size() > 1000000) { map.clear(); } } }
输出:
***************
newThread: 9
newThread: 517c804b
mainThread: 1
mainThread: 138b9a72
##############
TIMED_WAITING:等待特定时间
情况分析(Block的时候已经有说明)
Thread.sleep
Object.wait with timeout
Thread.join with timeout
LockSupport.parkNanos
LockSupport.parkUntil
jvm的线程的状态定义如下:
public enum State { /** * Thread state for a thread which has not yet started. */ NEW, /** * Thread state for a runnable thread. A thread in the runnable * state is executing in the Java virtual machine but it may * be waiting for other resources from the operating system * such as processor. */ RUNNABLE, /** * Thread state for a thread blocked waiting for a monitor lock. * A thread in the blocked state is waiting for a monitor lock * to enter a synchronized block/method or * reenter a synchronized block/method after calling * {@link Object#wait() Object.wait}. */ BLOCKED, /** * Thread state for a waiting thread. * A thread is in the waiting state due to calling one of the * following methods: *
-
*
- {@link Object#wait() Object.wait} with no timeout *
- {@link #join() Thread.join} with no timeout *
- {@link LockSupport#park() LockSupport.park} *
A thread in the waiting state is waiting for another thread to * perform a particular action. * * For example, a thread that has called Object.wait() * on an object is waiting for another thread to call * Object.notify() or Object.notifyAll() on * that object. A thread that has called Thread.join() * is waiting for a specified thread to terminate. */ WAITING, /** * Thread state for a waiting thread with a specified waiting time. * A thread is in the timed waiting state due to calling one of * the following methods with a specified positive waiting time: *
-
*
- {@link #sleep Thread.sleep} *
- {@link Object#wait(long) Object.wait} with timeout *
- {@link #join(long) Thread.join} with timeout *
- {@link LockSupport#parkNanos LockSupport.parkNanos} *
- {@link LockSupport#parkUntil LockSupport.parkUntil} *