2021-04-13 15:49:23

Java中高级高并发与多线程系列(四):线程运行状态的切换与操作


Java中高级高并发与多线程系列(四):线程运行状态的切换与操作

首先声明,本系列文章分享都是我自己的学习理解以后,原创手敲,可能包含错误的观点和理解,仅供参考,如遇错误的地方欢迎指正。

首先先明确,本文讨论的线程运行状态,是线程在 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()方法完成时,我们就认为它终止了。

线程的操作

本小节的示例代码公开在:https://github.com/renfei/demo/blob/master/java/ConcurrentDemo/src/main/java/net/renfei/demo/concurrent/ThreadOperationDemo.java

线程的命名

每个线程都有个名字,即使你不手动起名,也会有个默认的自增名字,当我们给线程起名时,在实例化的时候就可以传入,例如:

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://www.renfei.net/posts/1003496
评论与留言
以下内容均由网友提交发布,版权与真实性无法查证,请自行辨别。

本站有缓存策略,时间约2小时后能看到您的评论。本站使用自动审核机制,如果您的内容包含广告/谩骂/恐怖/暴力/涉政等不和谐内容将无法展示!


本站有缓存策略,时间约2小时后能看到您的评论。本站使用自动审核机制,如果您的内容包含广告/谩骂/恐怖/暴力/涉政等不和谐内容将无法展示!

关注任霏博客
扫码关注「任霏博客」微信订阅号
微博:任霏博客网
Twitter:@renfeii
Facebook:任霏