概述
这一篇文章总结一下线程是怎么从生到死的,状态是怎么转换的。
线程6种状态:
如果想要确定线程当前的状态,可以通过 getState() 方法,并且线程在任何时刻只可能处于 1 种状态。
- New(新创建)
- Runnable(可运行)
- Blocked(被阻塞)
- Waiting(等待)
- Timed Waiting(计时等待)
- Terminated(被终止)
1、New 新创建
New 表示线程被创建但尚未启动的状态。
new Thread() 新建一个线程时,如果线程没有开始运行 start() 方法,所以也没有开始执行 run() 方法里面的代码,那么此时它的状态就是 New。
一旦线程调用了 start(),它的状态就会从 New 变成 Runnable。
2、Runnable 可运行
Java 中的 Runable 状态对应操作系统线程状态中的两种状态,分别是 Running 和 Ready。
也就是说,Java 中处于 Runnable 状态的线程有可能正在执行,也有可能没有正在执行,正在等待被分配 CPU 资源。
所以,如果一个正在运行的线程是 Runnable 状态,当它运行到任务的一半时,执行该线程的 CPU 被调度去做其他事情,导致该线程暂时不运行,它的状态依然不变,还是 Runnable,因为它有可能随时被调度回来继续执行任务。
3、阻塞状态 Blocked(被阻塞)
阻塞状态包括三种状态,分别是 Blocked(被阻塞)、Waiting(等待)、Timed Waiting(计时等待)。
Runnable 状态进入 Blocked 状态只有一种可能,就是进入 synchronized 保护的代码时没有抢到monitor锁,无论是进入 synchronized 代码块,还是 synchronized 方法,都是一样。
什么时候转换下一状态?
当处于 Blocked的线程抢到 monitor 锁,就会从 Blocked 状态回到Runnable 状态。
4、阻塞状态 Waiting(等待)
线程进入 Waiting 状态有三种可能性。
1.没有设置 Timeout 参数的 Object.wait() 方法。
2.没有设置 Timeout 参数的 Thread.join() 方法。
3.LockSupport.park() 方法。
什么时候会进入Waiting状态呢?
1.ReentrantLock线程在获取这种锁时没有抢到该锁就会进入 Waiting 状态,因为本质上它执行了 LockSupport.park() 方法。
2.Object.wait()
3.Thread.join()
什么时候转换下一状态?
1、执行了 LockSupport.unpark(),或者 join 的线程运行结束,或者被中断时才可以进入 Runnable 状态。
2、其他线程调用notify() 或 notifyAll()来唤醒(有条件)
其他线程调用notify() 或 notifyAll()来唤醒(有条件),它会直接进入 Blocked 状态,为什么?
因为唤醒 Waiting 线程的线程如果调用 notify() 或 notifyAll(),要求必须首先持有该 monitor 锁,所以处于Waiting 状态的线程被唤醒时拿不到该锁,就会进入 Blocked 状态。
直到执行了 notify()/notifyAll() 的唤醒它的线程执行完毕并释放 monitor 锁,才可能轮到它去抢夺这把锁,如果它能抢到,就会从 Blocked 状态回到 Runnable 状态。
5、阻塞状态 Timed Waiting(计时等待)
Timed Waiting跟Waiting的区别就是Timed Waiting 会等待超时,由系统自动唤醒,或者在超时前被唤醒信号唤醒,区别仅在于有没有时间限制。
什么时候线程进入 Timed Waiting 状态?
1.设置了时间参数的 Thread.sleep(long millis) 方法;
2.设置了时间参数的 Object.wait(long timeout) 方法;
3.设置了时间参数的 Thread.join(long millis) 方法;
4.设置了时间参数的 LockSupport.parkNanos(long nanos) 方法和 LockSupport.parkUntil(long deadline) 方法。
什么时候转换下一状态?
1、执行 notify() 和 notifyAll() 也是一样的道理,它们会先进入 Blocked 状态,然后抢夺锁成功后,再回到 Runnable 状态。
2、超时时间到了且能直接获取到锁。直接恢复到 Runnable 状态
3、join的线程运行结束/被中断。直接恢复到 Runnable 状态
4、LockSupport.unpark()直接恢复到 Runnable 状态
6、Terminated 终止
什么时候线程进入Terminated 状态?
1.run() 方法执行完毕,线程正常退出。
2.出现一个没有捕获的异常,终止了 run() 方法,最终导致意外终止。
7、注意点
线程生命周期不可逆:一旦进入 Runnable 状态就不能回到 New 状态;一旦被终止就不可能再有任何状态的变化。所以一个线程只能有一次 New 和 Terminated 状态,只有处于中间状态才可以相互转换。
最后
以上就是仁爱荔枝为你收集整理的4.线程的生命周期(6种状态转换)线程6种状态:1、New 新创建2、Runnable 可运行3、阻塞状态 Blocked(被阻塞)4、阻塞状态 Waiting(等待)5、阻塞状态 Timed Waiting(计时等待)6、Terminated 终止7、注意点的全部内容,希望文章能够帮你解决4.线程的生命周期(6种状态转换)线程6种状态:1、New 新创建2、Runnable 可运行3、阻塞状态 Blocked(被阻塞)4、阻塞状态 Waiting(等待)5、阻塞状态 Timed Waiting(计时等待)6、Terminated 终止7、注意点所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复