线程状态
Java
中线程状态有六种,定义在Thread
类中的State
枚举类中
NEW
:初始状态,线程创建之后还没有开始运行。RUNNABLE
:可运行状态,线程正在运行或者已经就绪等待CPU
资源。BLOCKED
:阻塞状态,因为竞争锁而发生阻塞。WAITING
:等待状态,线程等待其他线程执行特定的动作。TIMED_WAITING
:计时等待状态,TERMINATED
:终止状态,线程已经执行结束。
线程状态转换
根据线程状态转换图,来详细介绍不同状态的转换方式
① NEW -> RUNNABLE
- 调用线程的
start()
方法后,状态由NEW
转换成RUNNABLE
② RUNNABLE -> WAITING
以下几种情况需要注意进入
WAITING
状态的是哪个线程
- 线程
t
通过synchronized(obj)
获取到对象锁后调用obj.wait()
方法时,t
线程从RUNNABLE
转换为WAITING
- 调用
t.join()
、LockSupport.park()
方法,当前线程状态由RUNNABLE
转换成WAITING
③ WAITING -> RUNNABLE
基于②的情况,调用obj.notify()
、obj.notifyAll()
、t.interrupt()
方法时
- 竞争锁成功,状态由
WAITING
转换为RUNNABLE
- 竞争锁失败,状态由
WAITING
转换为BLOCKED
,对应图中⑧的状态
或者调用LockSupport.unpark(t)
方法时,t
线程状态会由WAITING
转换为RUNNABLE
④ RUNNABLE -> TIMED_WAITING
这里同样需要注意发生状态转换的是哪个线程
- 线程
t
通过synchronized(obj)
获取到对象锁后调用obj.wait(timeout)
方法时,t
线程从RUNNABLE
转换为TIMED_WAITING
- 调用
Thread.sleep(timeout)
、t.join(timeout)
、LockSupport.parkNanos(timeout)
、LockSupport.parkUntil(timeout)
时,当前线程状态由RUNNABLE
转换为TIMED_WAITING
⑤ TIMED_WAITING -> RUNNABLE
基于④的情况下,当调用obj.notify()
、obj.notifyAll()
、t.interrupt()
方法时,
- 竞争锁成功,状态由
TIMED_WAITING
转换为RUNNABLE
- 竞争锁失败,状态由
TIMED_WAITING
转换为BLOCKED
,对应图中⑨的状态
调用LockSupport.unpark()
方法或者线程等待时间到了,状态由TIMED_WAITING
转换为RUNNABLE
⑥ RUNNABLE -> BLOCKED
当线程尝试获取synchronized
对象锁时,如果竞争失败,线程状态会由RUNNABLE
转换为BLOCKED
⑦ BLOCKED -> RUNNABLE
当持有synchronized
对象锁的线程执行完毕,会唤醒处于BLOCKED
状态的锁重新竞争,如果t
线程竞争成功,状态会由BLOCKED
转换为RUNNABLE
⑩ RUNNABLE -> TERMINATED
线程任务执行完毕,状态由 RUNNABLE
转换为TERMINATED