深入理解线程状态转换。
- 单向是只能从一个状态转向另一个状态
- 双向可以相互转向
图中的各个状态
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