• 3.Java线程的状态


    1 Java线程的6种状态

    在单线程环境下,线程的生命周期就是“创建、执行和终止”,但是在多线程环境下就不能这么分了。

    Java的线程有6种基本的方式,如下:

    • New:初始状态,线程被构建,但是还没有调用start()方法。

    • Runnable:运行状态,Java线程将操作系统的就绪和运行两种状态笼统的地称作“运行中”。

    • Blocked:阻塞状态,当线程执行了synchronized代码,并且没有抢到锁时就会变成该状态。

    • WAITING:等待状态,表示线程进入等待状态,进入该状态表示当前线程需要等待其他线程通知或者中断。

    • TIME_WAITING:超时等待状态,该状态与WAITING是不同的,该状态可以再指定的时间自行返回。

    • TERMINED:终止状态,表示当前线程已经执行完毕、

    在这个过程中,Blocked和waing什么区别呢?导致blocked只有一种情况,就是锁等待(Synchronized),这两者没有本质的区别,理解为定义或者发生的背景不一样就行了。

    这几种状态之间的转换关系是:

    上图中lockSupport用来创建lock锁的基本线程阻塞单元。LockSupport提供的是一个许可,如果存在许可,线程在调用park的时候会立马返回,此时许可会立马被消费掉,如果没有许可,则会阻塞。

    下面我们使用多个例子来进一步演示几种状态。

    2. 阻塞状态

    阻塞状态是一种特殊的状态,WAITING,TIME_WAITING,BLOCKED都属于阻塞状态,IO也会引起阻塞状态。 阻塞状态也不止一种情况,有waiting,time_waiting,blocked,io阻塞等 。我们现在就用多个例子来演示一下。

    TIME_WAITING状态

    1. public class TimedWaitingStatusExample {
    2.   public static void main(String[] args) {
    3.       new Thread(() -> {
    4.           try {
    5.               TimeUnit.SECONDS.sleep(10000);
    6.           } catch (InterruptedException e) {
    7.               e.printStackTrace();
    8.           }
    9.       }, "TIME_WAITING").start();
    10.   }
    11. }

    运行之后 ,我们使用jstack看一下堆信息,其中有如下一段内容:

    这里,我们可以看到线程的状态就是TIMED_WAITING状态,也就是sleeping状态。

    WAITING状态

    1. public class WaitingStatusExample {
    2.   public static void main(String[] args) {
    3.       new Thread(()->{
    4.           synchronized (WaitingStatusExample.class){
    5.               try {
    6.                   WaitingStatusExample.class.wait();
    7.               } catch (InterruptedException e) {
    8.                   e.printStackTrace();
    9.               }
    10.           }
    11.       },"WAITING").start();
    12.   }
    13. }

    我们同样使用jstack看一下其状态:

     我们可以看到WAITING和TIME_WAITING是不一样的,TIME_WAITING就是在sleep,而WAITING则是一致在等待资源(on object monitor)。

    Blocked状态

    我们再看Blocked状态的例子:

    1. public class BlockedStatusExample implements Runnable {
    2.   public static void main(String[] args) {
    3.       new Thread(new BlockedStatusExample(), "BLOCKED_T1").start();
    4.       new Thread(new BlockedStatusExample(), "BLOCKED_T2").start();
    5.   }
    6.   @Override
    7.   public void run() {
    8.       synchronized (BlockedStatusExample.class) {
    9.           //一直不释放锁
    10.           while (true) {
    11.           }
    12.       }
    13.   }
    14. }

    此时使用jstack查看进程的状态为:

     此时我们可以看到BLOCKED_T1抢到了资源,状态为Runnable,而BLOCKED_T2没有抢到锁,状态为监听状态。

    而且对比发现BLOCKED_T2的监听状态与上面WAITING的状态基本一致的,这就说明两种状态本质上是一致的,只不过触发的条件不一样罢了。

    结论就是:TimeWaiting状态就是sleep状态,会释放占有的资源。而waiting和Blocked状态不仅不释放已经占有的资源,还在等待其他资源。

  • 相关阅读:
    【晶振专题】案例:为什么对着STM32低速32.768K晶振哈口气就不起振了?
    python使用matplotlib.pyplot画图时总会提示“内核似乎挂掉了,很快就会自动重启”
    MYSQLg高级-------分库分表之核心Sharding-Proxy 简介
    第47节——使用bindActionCreators封装actions模块
    unity URP 利用particle system制作简单的shader交互
    [Python] 元组操作及方法总结
    教授先生带你学习并查集
    第43天:python操作mysql、视图及触发器、事务及索引
    Python爬虫——Scrapy框架使用实例及执行过程
    Koltin协程:Flow的触发与消费
  • 原文地址:https://blog.csdn.net/xueyushenzhou/article/details/126497024