解析java中线程的生命周期
1 两种主流说法
1.1 官方API文档说法
线程的生命周期有NEW(新建)、RUNNABLE(可运行状态)、Blocked(阻塞状态)、WAITING(等待状态)、TIMED_WAITING(超时等待状态)、TERMINATED(退出状态)
1.2 Runnable状态细分说法
线程的生命周期有NEW(新建)、READY(就绪状态)、RUNNING-(运行状态)、Blocked(阻塞状态)、WAITING(等待状态)、TIMED_WAITING(超时等待状态)、TERMINATED(退出状态)
其中READY状态和RUNNING状态是由RUNNABLE状态细分下来的
2 具体分析(细分法为例)
2.1 新建(NEW)
尚未启动的线程就处于该状态
具体指的是只创建了线程对象,并没有提供.start方法去开启它
2.2 就绪(Ready)
线程对象调用了start方法就进入了该状态
进入就绪状态不一定会去运行,因为需要看cpu是否给你分配资源
但是通过线程对象.getState方法得到的状态只是6种,因此并不知晓该Runnable状态到底是属于Ready状态呢还是属于Running状态呢
2.3 运行(Running)
当一个线程处于就绪状态,且它成功的在本轮cpu资源争夺战中获得了胜利,因此它会进入Running运行状态
注意:只是代表抢到的时间片段对应的那段时间是可运行状态,当时间片用完时,会进入就绪状态,再进入下一轮的时间片资源争夺战。
因而就绪状态和运行状态是可以相互之间转换的
2.4 阻塞(BLOCKED)
被阻塞的等待监视器锁定的线程处于该状态
例子: 同步代码块或者同步方法,就限制了该方法或者代码块只允许符合条件的其中一个线程对象使用,保证了数据的安全性
2.5 等待(WAITING)
正在等待另外一个线程执行特定动作的线程处于此状态
例如 o.waiting;t.join
2.6 超时等待(TIMED_WAITING)
正在等待另一个线程执行动作达到指定等待时间的线程处于此状态。
说白了就是该线程需要过一段时间才会超时等待状态转换成就绪状态
此时若抢到了时间片资源,那么它会从它遇到超时等待状态的下一行代码执行
并不是又重来一次(记录了它进入超时状态之前的状态和位置)
例子: Thread.sleep方法 线程睡眠方法
2.7 结束(TERMINATED)
已经退出的线程处于该状态(调用了join方法就能进入该状态)