• 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状态不仅不释放已经占有的资源,还在等待其他资源。

  • 相关阅读:
    (附源码)node.js电商管理系统 毕业设计 251001
    软件加密系统Themida应用程序保护指南(一):应用信息界面
    哪里有期货开户的正规途径?
    JS-获取网页滑动距离,并实时监听
    MySQL触发器
    string类接口介绍及应用
    基于Matlab实现元胞自动机(CA)
    C++ 智能指针常用总结
    Swagger
    第189题|幂级数的展开的常规方法(二)|武忠祥老师每日一题
  • 原文地址:https://blog.csdn.net/xueyushenzhou/article/details/126497024