进程的状态参考操作系统:创建态、就绪态、运行态、阻塞态、终止态
线程由生到死的完整过程(生命周期):当线程被创建并启动以后,既不是一启动就进入了执行状态,也不是一直处于执行状态,在 API 中 java.lang.Thread.State
这个枚举中给出了六种线程状态:
线程状态 | 导致状态发生条件 |
---|---|
NEW(新建) | 线程刚被创建,但是并未启动,还没调用 t.start() 方法,只有线程对象,没有线程特征 |
Runnable(可运行) | 线程可以在 Java 虚拟机中运行的状态,可能正在运行自己代码,也可能没有,这取决于操作系统处理器,调用了 t.start() 方法:就绪(经典叫法),注意它涵盖了操作系统层面的【就绪态】【运行态】【阻塞态】(由于BIO导致的线程阻塞在JAVA中无法区分,仍认为是可运行的) |
Blocked(阻塞) | 当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入 Blocked 状态;当该线程持有锁时,该线程将变成 Runnable 状态 |
Waiting(无限等待) | 一个线程在等待另一个线程执行一个(唤醒)动作时,该线程进入 Waiting 状态,进入这个状态后不能自动唤醒,必须等待另一个线程调用 notify 或者 notifyAll 方法才能唤醒 |
Timed Waiting (限期等待) | 有几个方法有超时参数,调用将进入 Timed Waiting 状态,这一状态将一直保持到超时期满或者接收到唤醒通知。带有超时参数的常用方法有 Thread.sleep 、Object.wait |
Teminated(结束) | run 方法正常退出而死亡,或者因为没有捕获的异常终止了 run 方法而死亡 |
⚠️【Blocked】【Waiting】【Timed Waiting】是Java API层面对【阻塞态】的细分
NEW → RUNNABLE:当调用 t.start() 方法时,由 NEW → RUNNABLE
RUNNABLE <–> WAITING:
调用 obj.wait() 方法时
调用 obj.notify()、obj.notifyAll()、t.interrupt():
- 竞争锁成功,t 线程从 WAITING → RUNNABLE
- 竞争锁失败,t 线程从 WAITING → BLOCKED
当前线程调用 t.join() 方法,注意是当前线程在 t 线程对象的监视器上等待
当前线程调用 LockSupport.park() 方法
RUNNABLE <–> TIMED_WAITING:调用 obj.wait(long n) 方法、当前线程调用 t.join(long n) 方法、当前线程调用 Thread.sleep(long n)
RUNNABLE <–> BLOCKED:t 线程用 synchronized(obj) 获取了对象锁时竞争失败