java中线程的生命周期
线程的生命周期也叫做线程的状态
在java中Thread类下的枚举类State定义了线程的6种状态
public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }
各个状态的简单说明:
NEW(新建 ):线程刚被创建,还没有调用start()
方法
RUNNABLE(可运行):一旦调用start()
方法之后,线程处于 runnable 状态,可能正在运行也可能等待cpu分配时间。注意:Java API层面的RUNNABLE状态涵盖了操作系统层面的可运行状态、运行状态和阻塞状态
BLOCKED(阻塞):受阻塞状态,表示线程等待某个监视器锁
WAITING(等待):表示线程进入等待状态,进入该状态表示当前线程需要等待其他线程做出一些特定动作(通知或中断)
TIMED_WAITING(计时等待):计时等待状态,无需等待其他线程的唤醒,可以在指定的时间后被系统自动唤醒
TERMINATED(终止):终止状态,表示当前线程已经执行完毕
状态图:来自《Java并发编程的艺术》
各个状态之间的转换
NEW-->
RUNNABLE
调用t.start()
方法
RUNNABLE<-->
WAITING
(1)当 t 线程使用 synchronized(obj) 获取锁对象后
调用obj.wait()
方法,t 线程由 RUNNABLE-->
WAITING
当调用obj.notify()
,obj.notifyAll()
,t.interrupt()
时:
-
竞争锁成功,t 线程由 WAITING
-->
RUNNABLE -
竞争锁失败,t 线程由 WAITING
-->
BLOCKED
(2)当前线程中使用 t 线程调用t.join()
,当前线程由 RUNNABLE-->
WAITING
-
注意是当前线程在 t 线程对象的监视器等待
t 线程运行结束或者调用了当前线程的interrupt()时,当前线程由 WAITING-->
RUNNABLE
(3)当前线程调用LockSupport.park()
方法,当前线程会从 RUNNABLE-->
WAITING
调用LockSupport.unpark(目标线程)
或者调用线程的interrupt()
目标线程会由 WAITING-->
RUNNABLE
RUNNABLE<-->
TIMED_WAITING
(1)当 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
(2)当前线程中使用 t 线程调用t.join(long n)
,当前线程从RUNNABLE -->
TIMED_WAITING
-
注意是当前线程在t 线程对象的监视器上等待
当前线程等待时间超过了 n 毫秒,或 t 线程运行结束,或调用了当前线程的 interrupt() 时,当前线程从 TIMED_WAITING -->
RUNNABLE
(3)当前线程调用Thread.sleep(long n)
,当前线程从 RUNNABLE -->
TIMED_WAITING
当前线程等待时间超过了 n 毫秒,当前线程从 TIMED_WAITING-->
RUNNABLE
(4)当前线程调用LockSupport.parkNanos(long nanos)
或LockSupport.parkUntil(long millis)
时,当前线程从 RUNNABLE -->
TIMED_WAITING
调用LockSupport.unpark(目标线程)
或调用了线程的interrupt()
,或等待超时,会让目标线程从 TIMED_WAITING-->
RUNNABLE
RUNNABLE <--> BLOCKED
t 线程用synchronized(obj)
获取了对象锁时如果竞争失败,从 RUNNABLE --> BLOCKED
RUNNABLE --> TERMINATED
当前线程所有代码运行完毕或者产生异常没处理,进入TERMINATED