JavaEE——线程的状态

目录

前言

一、NEW 和 TERMINSTED

二、就绪状态

三、阻塞状态

总结


前言

PCB 中的状态主要分为就绪状态和阻塞状态两种,而在 Java 中,则对线程的状态做了进一步的细分,主要有:NEW、TERMINSTED、RUNNABLE、BLOCKED、WAITING 和 TIMED_WAITING 。下面就是对这几种状态进行逐一分析:

一、NEW 和 TERMINSTED

NEW 状态表示的是已经安排好了线程相对应的工作,但是还没开始做,就例如老师布置了作业,你也记下来在本子上了,但是还没开始做。具体点讲就是:Thread 对象已经创建好了,但是还没调用 start 方法,下面就通过代码来进行演示:

我们可以使用 Thread 类的 getState( ) 方法来获取到当前线程的状态

public class Demo1 {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            System.out.println("hello Thread!");
        });

        System.out.println(t.getState());

        t.start();
    }
}

 

从代码中我们可以看到,在 t 线程调用 start 方法之前,我们先打印出当前 t 线程所处的状态,因此我们可以看到执行 run 方法打印 hello Thread 之前先打印出了一个 NEW ,这便表明了未调用 start 方法但是已经创建出来了的 Thread 对象所处的状态就是 NEW 状态。

而 TERMINSTED 状态指的是线程已经完成了工作,再具体一点便是:线程已经执行完 run 方法了,但是 Thread 对象还未被销毁。

这是因为系统内核创建的线程和 Thread 对象的生命周期并不是完全一致的。

一般情况下都是先创建了 Thread 对象,然后再手动调用 start 方法,让系统内核创建出一个实际的线程。而消亡的时候,就可能是 Thread 先消亡,例如:Thread 对象在线程还未执行完 run 方法的时候就不再指向该线程了,并且不再指向任何对象,那么此时该引用就会被销毁回收。也有可能是线程先执行完,但是 Thread 对象还在。

public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            System.out.println("hello Thread!");
        });

        t.start();
        
        t.join();
        System.out.println(t.getState());
    }
}

 

上述代码中,我们使用了 join 方法让主线程等待 t 线程执行结束之后再打印出 t 线程的状态,就可以获取到 t 线程 run 方法执行完了之后的状态,由上图可知的确在 run 方法打印出 hello Thread 之后打印出 TERMINSTED 。

二、就绪状态

Java 中的就绪状态使用 RUNNABLE 来表示。

就绪状态分为以下两种:

1)线程正在 cpu 上运行

2)线程在排队,但是时刻准备着到 cpu 上执行

这两种状态都统称为就绪状态,因此无需纠结该线程创建出来之后是否在 cpu 执行调度。

public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while (true) {

            }
        });
        t.start();

        Thread.sleep(1000);
        System.out.println(t.getState());
    }
}

当我们执行上述代码时,start 方法启动 t 线程,然后先休眠 1000ms 保证 t 线程此时已经被启动,又由于 t 线程的 run 方法内是死循环,因此只要我们不手动停止,此时打印其状态都会为 RUNNABLE 。

三、阻塞状态

Java 中的阻塞状态分为三种,主要的区别就是造成阻塞的原因不同:

1)BLOCKED:因为锁发生了阻塞

2)WAITING:因为调用了 wait 发生了阻塞

3)TIMED_WAITING:因为调用了 sleep 或者带最大等待时间的 join 发生了阻塞,也即是带时间的阻塞则为 TIMED_WAITING,否则则为 BLOCKED 或者 WAITING

例如:

public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        t.start();

        Thread.sleep(1000);
        System.out.println(t.getState());
    }
}

上述代码中,仍然是先休眠 1000ms 保证 t 线程已经启动了,然后打印 t 线程的状态,由于 t 线程内为休眠 5000ms ,时间比较久,因此此时 t 线程为:因为 sleep 导致的阻塞状态——TIMED_WAITING 。

 

总结

上述的状态根据时间的先后,可以汇总成一张简单的图示:

 

充分了解这些线程状态,可以帮助我们解决线程执行过程中出现的 bug :在线程执行出现问题时,通过调试窗口或者 jconsole 等工具来观察线程,可以根据线程状态来判断出具体是哪里出现了问题,进而做出修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值