一、Java Thread文档
关于Java的线程状态,Java Thread文档讲的非常的清楚了,如果英文水平有4级的话,建议直接阅读文档。
二、Java线程状态
java的线程一共有6个状态:New,Runnable,Waiting,Timed_Waiting,Blocked,Terminate。
这里Java使用Thread
类的内部枚举类进行表示,简要信息如下:
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
}
需要注意的是,Java的线程状态线程在JVM上的状态,和操作系统的线程状态无关。也就是说,当一个Java线程处于Blocked状态时,并不代表它在操作系统层面的状态是Blocked,只能说明它在JVM层面的状态是Blocked。这一点在文档上有说明:
These states are virtual machine states which do not reflect any operating system thread states.
这些状态仅仅表示VM(虚拟机)的状态,并不代表操作系统的线程状态。
三、Java线程状态详解
- New:当一个线程刚刚被创建(
new
),但是还未被启动(调用start()
方法),这个线程就处于New状态; - Runnable:一个线程处于可以被调用的状态时,就是Runnable状态;
- Blocked:一个线程要进入
synchronized
同步代码块,但相关锁被其它线程占有时,线程就会进入Blocked。当线程被notify()
方法或者notifyAll()
方法唤醒时,线程也会进入Blocked状态; - Waiting:线程调用
Object#wait()
,Thread.join()
,LockSupport.park()
方法时,就会进入Waiting状态; - Time_Waiting:线程调用
Thread.sleep()
,Object#wiat(long timeout)
,Thread.join(long timeout)
,LockSupport.parkNanos()
,LockSupport.parkUntil()
时,就会进入Time_Waiting状态; - Terminate:代表线程已经终止。
四、Java线程状态转换
上一张我在网上找的图:
说说几个值得注意的点:
- 调用
notify()
和notifyAll()
方法并不会将线程状态从Waiting和Timed_Waiting转换为Runnable,而是将线程状态转换为Blocked。 - 图中并没有画出
LockSupport.unpark()
会将线程的线程线程状态转换,我在网上也没有找到相关的资料,个人认为LockSupport.unpark()
会将线程状态从Waiting或者Timed_Waiting转换为Runnable。 - 那如果我调用了
Lock#lock()
,线程获取锁失败,线程会进入Blocked还是Waiting状态?线程调用Lock#lock
,其实本质是调用了LockSupport.park()
,我们可以写一个简单的程序验证一下:
public class ThreadState {
private static final ReentrantLock LOCK = new ReentrantLock();
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
new Thread(new MyThread(), "Thread-" + i).start();
}
loop();
}
private static class MyThread implements Runnable {
@Override
public void run() {
LOCK.lock();
loop();
}
}
private static void loop() {
for (; ; ) {
// do nothing
}
}
}
运行程序后,使用VisualVM将线程状态Dump下来,部分如下:
"Thread-0" #13 prio=5 os_prio=0 cpu=19062.50ms elapsed=19.85s tid=0x0000015e40a21000 nid=0x2730c runnable [0x0000000d701fe000]
java.lang.Thread.State: RUNNABLE
at thread.ThreadState.loop(ThreadState.java:29)
at thread.ThreadState$Thread.run(ThreadState.java:24)
at java.lang.Thread.run(java.base@11.0.2/Thread.java:834)
Locked ownable synchronizers:
- <0x0000000089b4f998> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
"Thread-1" #14 prio=5 os_prio=0 cpu=0.00ms elapsed=19.85s tid=0x0000015e40a22000 nid=0x269c4 waiting on condition [0x0000000d702ff000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@11.0.2/Native Method)
- parking to wait for <0x0000000089b4f998> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(java.base@11.0.2/LockSupport.java:194)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(java.base@11.0.2/AbstractQueuedSynchronizer.java:885)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(java.base@11.0.2/AbstractQueuedSynchronizer.java:917)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@11.0.2/AbstractQueuedSynchronizer.java:1240)
at java.util.concurrent.locks.ReentrantLock.lock(java.base@11.0.2/ReentrantLock.java:267)
at thread.ThreadState$Thread.run(ThreadState.java:23)
at java.lang.Thread.run(java.base@11.0.2/Thread.java:834)
Locked ownable synchronizers:
- None
"Thread-2" #15 prio=5 os_prio=0 cpu=0.00ms elapsed=19.85s tid=0x0000015e40a2b000 nid=0x24170 waiting on condition [0x0000000d703ff000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@11.0.2/Native Method)
- parking to wait for <0x0000000089b4f998> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(java.base@11.0.2/LockSupport.java:194)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(java.base@11.0.2/AbstractQueuedSynchronizer.java:885)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(java.base@11.0.2/AbstractQueuedSynchronizer.java:917)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@11.0.2/AbstractQueuedSynchronizer.java:1240)
at java.util.concurrent.locks.ReentrantLock.lock(java.base@11.0.2/ReentrantLock.java:267)
at thread.ThreadState$Thread.run(ThreadState.java:23)
at java.lang.Thread.run(java.base@11.0.2/Thread.java:834)
Locked ownable synchronizers:
- None
可以看出,Thread-1和Thread-2由于调用了LockSupport.park()
都处于Waiting状态。