深入理解线程状态转换。
- 单向是只能从一个状态转向另一个状态
- 双向可以相互转向
图中的各个状态
RUNABLE
是 JAVA
层面的状态。里面的那些运行可运行状态、运行状态、阻塞状态,JAVA
是看不出来的。
假设有线程 Thread t
NEW -> RUNNABLE
- 当调用
t.start()
方法时,由NEW -> RUNNABLE
RUNABLE <-> WAITING 情况2
t
线程用 synchronized(obj)
获取了对象锁后
- 调用
obj.wait()
方法时,t
线程从RUNNABLE -> WAITING
- 调用
obj.notify()
,obj.notifyALL()
,t.interrupt(
) 时- 竞争成功,
t
线程从WAITING -> RUNNABLE
- 竞争失败,
t
线程从WAITING -> BLOCKED
- 竞争成功,
RUNNABLE <-> WAITING 情况3
- 当线程调用
t.join()
方法时,当前线程从RUNNABLE -> WAITING
- 逐一时当前线程在
t
线程对象的监视器等待
- 逐一时当前线程在
- t 线程运行结束,或调用了当前线程的
interrupt()
时,当前线程从WAITING -> RUNNABLE
RUNNABLE <-> WAITING 情况4
- 当前线程调用了
LockSupport.park()
方法会让当前线程从RUNNABLE -> WAITING
- 调用
LockSupport.unpark(目标线程)
或调用了线程的interrupt()
,会让目标线程从WAITING -> RUNNABLE
RUNNABLE <-> TIMED_WAITING 情况5
t
线程用synchronized(obj)
获取对象锁后- 调用
obj.wait(long n)
方法,t
线程从RUNNABLE -> TIMED_WAITING
t
线程等待时间超过n
毫秒,或调用obj.notify()
、obj.notifyAll()
、t.interrupt()
时- 竞争锁成功,
t
线程从TIMED_WAITING -> RUNNABLE
- 竞争锁失败,
t
线程从TIMED_WAITING -> BLOCKED
- 竞争锁成功,
- 调用
RUNNABLE <-> TIMED_WAITING 情况6
- 当前线程调用
t.join(long n)
方法时,当前线程从RUNNABLE -> TIMED_WAITING
- 注意时当前线程在
t
线程对象的监视器等待
- 注意时当前线程在
- 当前线程等待时间超过了
n
毫秒,或t
线程运行结束,或调用了当前线程的interrupt()
时,当前线程从TIMED_WAITING -> RUNNABLE
RUNNABLE <-> TIMED_WAITING 情况7
- 当前线程调用
Thread.sleep(long n)
,当前线程从RUNNABLE -> TIMED_WAITING
- 当前线程等待时间超过
n
毫秒,当前线程从TIMED_WAITING -> RUNNABLE
RUNNABLE <-> TIMED_WAITING 情况8
- 当前线程调用
LockSupport.parkNanos(long nanos)
或LockSupport.parkUntil(long millils)
,当前线程从RUNNABLE -> TIMED_WAITING
- 调用
LockSupport.unpark(目标线程)
或调用了线程的interrupt()
,或是等待超时,会让目标线程从TIMED_WAITING -> RUNNABLE
RUNNABLE <-> BLOCKED 情况9
t
线程用sybchronized(obj)
获取了对象锁时如果竞争失败,从RUNNABLE -> BLOCKED
- 持
obj
锁线程的同步代码块执行完毕,会唤醒该对象所有的BLOCKED
线程重新竞争,如果其中t
线程竞争成功,从BLOCKED -> RUNNABLE
,其他失败线程依然BLOCKED
RUNNABLE <-> TERMINATED 情况10
当前线程执行完毕,进入 TERMINATED