线程生命周期
大约 2 分钟
当线程被创建并启动之后,它并不是一启动就进入了执行状态,同时也不会一直处于执行态。线程从启动到结束,需要经历五种状态,即:新建(New)
、就绪(Runnable)
、运行(Running)
、阻塞(Blocked)
和死亡(Dead)
。线程在运行过程中,会在就绪、运行、阻塞三个状态间反复切换,目的是避免某一个线程一直独占 CPU 造成资源浪费和任务阻塞。

新建状态(New)
当用 new 创建一个线程时,线程还没有开始运行,此时线程处于新建状态。处于新建状态的线程还没有开始运行。
就绪状态(Runnable)
一个新建的线程并不会自动运行,需要手动去调用线程的 start()
方法,当 start() 返回后,线程就处于就绪状态,等待处理器的调度。
运行状态(Running)
当线程被分配了 CPU 时间片后,就进入运行状态,此时才真正的执行 run()
方法里的内容。
阻塞状态(Blocked)
线程在运行过程中,可能会因为各种原因进入阻塞状态,比如:
- 等待阻塞(调用 wait(),进入等待队列):运行得线程执行
wait()
方法,JVM 会把该线程放入等待队列(waitting queue)中. - 同步阻塞(lock,锁):运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则 JVM 会把该线程放入到锁池(lock pool)中。
- 其它阻塞(sleep、join):运行的线程执行
Thread.sleep(long ms)
或t.join()
方法,或者发出了 IO 请求时,JVM 会把该线程设置为阻塞状态。当 sleep() 状态超时、join()等待线程终止或者超时、或者 IO 处理完毕时,线程才能重新装入可运行状态。
所谓线程的阻塞,就是正在运行的线程因为某种原因放弃了 CPU 使用权,即让出了 CPU timeslice,暂时停止运行。知道线程进入可运行状态,才有机会再次获取得 CPU timeslice 状态运行状态。
死亡状态(Dead)
有三种方式可以结束线程,也就是线程进入死亡状态:
- 线程正常执行 run() 方法结束;
- 线程执行过程中出现未捕获异常,导致线程猝死;
- 手动调用
stop()
结束线程,直接调用 stop() 方法很容易导致死锁,故不推荐使用。