前言
今天我们看一下线程的生命周期.我们在学习多线程时似乎并不是很看重线程的生命周期,或许是觉得它很简单,或许是因为面试的时候很少被问及,所以感觉它不是很重要.其实不然,熟练掌握线程生命周期的各个状态及状态间的转换,不仅有利于理解线程如何工作,而且对后面锁的理解很有帮助.
在讲线程的生命周期之前,先抛出一个问题:当使用阻塞IO等待用户输入时,此时线程是什么状态?
你可能会不假思索的回答是阻塞状态.真的是这样吗? 如果有兴趣你可以现在写一段程序去验证一下,看看ThreadState返回的是什么.是的,它会返回Runnable,而不是Blocked.为什么? 我会在后面详细说明,这里先卖个关子
操作系统线程生命周期
JVM线程的运行依赖于操作系统的线程,它对操作系统线程做了进一步封装.我们先看一下通用的操作系统线程的生命周期
过程如下:
- 首先我们创建一个线程,它的状态是New;
- 线程启动后,它的状态变成Ready.注意,此时它并不是真的开始工作,而是等待分配CPU时间片;
- 分配到时间片后,状态变成Running,此时真正开始工作;
- 工作过程中如果没有发生任何休眠或阻塞,那么线程正常运行结束,状态变为Terminated;
- 如果要执行某些休眠或阻塞操作,那么线程处于Blocked状态;
- 休眠结束或者阻塞操作完成,线程不能直接回到Running状态,而是先变成Ready状态,然后获取时间片后再变成Running
注意: 处于Blocked状态的线程可以被中断,进而变成Terminated.后面我们会讲到如何优雅的中断线程
总结
上面介绍操作系统线程的生命周期,分成了五个状态.并简单说明了状态间的转换.下一节我们会看一下JVM的线程生命周期,然后重点说明一下两者差异,以及JVM线程状态的转换.
再次强调:熟练掌握JVM线程状态的转换非常重要,它对后面将要讲解的"锁"的理解非常有帮助