Java中高级高并发与多线程系列(四):线程运行状态的切换与操作
2021年04月13日 15:49:23 · 本文共 1,847 字阅读时间约 6分钟 · 4,411 次浏览首先声明,本系列文章分享都是我自己的学习理解以后,原创手敲,可能包含错误的观点和理解,仅供参考,如遇错误的地方欢迎指正。
首先先明确,本文讨论的线程运行状态,是线程在 JVM 虚拟机中的状态,并不是 OS 操作系统中 CPU 调度的线程状态,虽然意思差不多,但并不是一个东西。
多线程系列全部演示代码公开在:https://github.com/renfei/demo/tree/master/java/ConcurrentDemo
Java 线程的 6 种状态
首先,要明确的是在 Java 中线程有 6 种状态,网络上包括 CSDN 上一群复制转载党无脑复制,不知道从哪复制的都在讲 5 种状态,我是亲自找的文档,我可以确定的是 6 种状态:
NEW:尚未启动的线程处于此状态。
RUNNABLE:在Java虚拟机中执行的线程处于此状态。
BLOCKED:等待监视器锁定而被阻止的线程处于此状态。
WAITING:无限期等待另一个线程执行特定操作的线程处于此状态。
TIMED_WAITING:在指定的等待时间内等待另一个线程执行操作的线程处于此状态。
TERMINATED:已退出的线程处于此状态。
特别说明:线程在给定的时间点只能处于一种状态。这些状态是不反映任何OS操作系统线程状态的JVM虚拟机状态。
当线程启动后,它可以在Runnable、Blocked、Waiting和Timed Waiting这几个状态之间切换,直到最后变成Terminated状态,线程终止。
6 种状态详细说明
初始状态(NEW)
当我们 new Thread 就会得到一个线程对象,这个时候这个线程对象就是初始状态(NEW)。
运行状态(RUNNABLE)
这里的运行状态(RUNNABLE)虽然是一个,但其实又分为两个可能性 READY、RUNNING,JDK 源码里是这样说的:Thread state for a runnable thread. A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.
翻译是处于可运行状态的线程正在Java虚拟机中执行,但它可能正在等待来自操作系统的其他资源,如处理器。
所以这里又分为两种可能 READY、RUNNING
READY 就绪状态说明已经可以被调度了,但还没有被调度到。
RUNNING 运行中,就是实实在在的正在运行。
阻塞状态(BLOCKED)
此线程需要获得某个锁才能继续执行,而这个锁目前被其他线程持有,所以进入了被动的等待状态,直到抢到了那个锁,才会再次进入"就绪"状态。
等待(WAITING)
代表此线程正处于无限期的主动等待中,直到有人唤醒它,它才会再次进入就绪状态。
超时等待(TIMED_WAITING)
代表此线程正处于有限期的主动等待中,要么有人唤醒它,在达到一定时间后它们会自动唤醒。
终止状态(TERMINATED)
当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。
线程的操作
线程的命名
每个线程都有个名字,即使你不手动起名,也会有个默认的自增名字,当我们给线程起名时,在实例化的时候就可以传入,例如:
Thread threadA = new Thread(myThread, "线程A");
线程的优先级
我们还可以为每个线程设置优先级,但是注意一下,这个优先级只是给调度器的一个建议,并不一定高优先级的会在低优先级的前面执行,只是给调度器一个建议优先调度谁,但不是一定先调度高的,我们可以这样设置:
threadC.setPriority(Thread.MAX_PRIORITY);
线程的中断
当我们想让线程停止的时候,就可以调用 interrupt() 中断方法,同时也可以使用 isInterrupted() 看来判断是否被中断,例如:
// 判断 threadA 是否被中断
if (!threadA.isInterrupted()) {
// 中断 threadA 的线程,线程的中断操作
threadA.interrupt();
}
线程的join
如果我们当前的进程需要另一个进程的运行结果或者说需要另一个进程先完成,我们就可以使用 join() 阻塞当前进程,等待 join 的这个进程执行完成以后当前进程再进行执行。
线程的yield
线程的 yield() 方法在很多地方被称作礼让,就是让出当前 CPU 时间片,让调度器调度下一个进程执行,注意这里只礼让一次,下一次被调度器选中以后还是会继续执行,这与 sleep() 不同。
版权声明:本文为博主「任霏」原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.renfei.net/posts/1003496
相关推荐
猜你还喜欢这些内容,不妨试试阅读一下- 前后端分离项目接口数据加密的秘钥交换逻辑(RSA、AES)
- OmniGraffle 激活/破解 密钥/密匙/Key/License
- Parallels Desktop For Mac 16.0.1.48911 破解版 [TNT]
- Redis 未授权访问漏洞分析 cleanfda 脚本复现漏洞挖矿
- CleanMyMac X 破解版 [TNT] 4.6.0
- OmniPlan 激活/破解 密钥/密匙/Key/License
- 人大金仓 KingbaseES V8 R3 安装包、驱动包和 License 下载地址
- Sound Control 破解版 2.4.2
- Parallels Desktop For Mac 15.1.4.47270 破解版 [TNT]
- Parallels Desktop For Mac 16.0.0.48916 破解版 [TNT]
- 博客完全迁移上阿里云,我所使用的阿里云架构
- 微软确认Windows 10存在bug 部分电脑升级后被冻结
- 大佬们在说的AQS,到底啥是个AQS(AbstractQueuedSynchronizer)同步队列
- 比特币(BTC)钱包客户端区块链数据同步慢,区块链数据离线下载
- Java中说的CAS(compare and swap)是个啥
- 小心免费主题!那些WordPress主题后门,一招拥有管理员权限
- 强烈谴责[wamae.win]恶意反向代理我站并篡改我站网页
- 讨论下Java中的volatile和JMM(Java Memory Model)Java内存模型
- 新版个人网站 NEILREN4J 上线并开源程序源码
- 我站近期遭受到恶意不友好访问攻击公告