#详细介绍:线程状态详解!!!

线程在操作系统中其自身是有一个自己的状态的,例如:线程还没运行,线程已结束,线程正在运行,线程堵塞等一系列状态,而Java Thread其实是对操作系统中线程的封装,把这些状态又进一步的精细化。那么如何查看线程的状态呢?这些状态分别用什么表示呢?,每个新状态代表的含义又是什么呢?

带着这些问题,让我们来进入本篇的学习!

目录

线程状态的分类

NEW 

TERMINATED

RUNNABLE

TIMED_WAITING(限时等待)

BLOCKED

WAITING

线程状态的转移



Java获取线程状态:调用getState方法,返回的是一个线程状态的枚举变量

线程状态的分类

  • NEW 

NEW 表示线程在操作系统中还没被创建出来,只是得到了一个线程实例对象,在启动线程之前获取的一个线程状态

上篇文章我们也介绍了,new了一个Thread 并不意味着创建了一个线程,只是获取到了一个线程对象,而真正创建线程的调用的start()方法,参考上篇文章,直接调用run方法和调用statrt方法的区别就能很好的体现

public class Test{
    public static void main(String[] args){
        Thread t = new Thread(() -> {
            System.out.println("hello world");
        });
        
        //此时线程t的实例已经创建好了,但是线程还没正式创建
        
        System.out.println(t.getState()); //此时获取 t 线程的状态 就是NEW状态了    
        t.start() //调用此处才会真正的创建线程
    } 
}

上述代码就表明,线程并没有开始执行,那么此时我们获取到的线程状态就为NEW状态

  • TERMINATED

线程执行结束,但是线程对象还在

展示代码:

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

        t.start(); //创建并启动线程
        try {
            Thread.sleep(1000); //主线程休眠1000毫秒,以确保t线程执行完毕
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //获取线程状态并打印
        System.out.println(t.getState());
    }
}

  • RUNNABLE

表示当前线程处于就绪态。

就绪态分为两种情况:

1. 线程正在CPU执行

2. 线程已经准备好了,正在排队,随时可以上CPU执行

//RUNNABLE状态:表示该线程正在执行或者已经准备好了,随时可以开始执行
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            while(true){
                //此处不写打印方法
                //因为print操作是一个加了锁(synchronized修饰)的方法。
                //只会同时打印一个
            }
        });

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

    }

 

上述代码 t 线程一直在执行,那么 t 线程的状态就为RUNNABLE(就绪态)

  • TIMED_WAITING(限时等待)

    限时等待: 表示线程正在休眠,一段时间后恢复的状态

    注意区分与WAITING不同点

    TIMED_WAITING 表示的是一定时间内休眠并不是死等,例如sleep或者带参数的join。

    如果直接调用join方法,不设置参数,那么此时线程一定是死等直到等待的线程结束,那么此时就不是TIMED_WAITING状态了,而是WAITING状态,所以注意和WAITING状态进行区分

    public static void main(String[] args) {
            Thread t1 = new Thread(() -> {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("hello world");
            });
    
            //执行线程t1
            t1.start();
    
            Thread t2 = new Thread(() -> {
                //此时线程 t2 等待线程 t1 执行 等待5000毫秒
                try {
                    t1.join(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
    
            //执行线程t2
            t2.start();
    
            //休眠一段时间让线程 t2 进入休眠
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println(t2.getState());
    
        }

     

    上述代码意思为:t2 线程等待 t1 线程 5000毫秒,在此期间,我们查看 t2 线程的状态就是TIMED_WAITING(限时等待)了。

    如果我们 t2 线程中的 join方法不设置参数,那么此时就为死等 t1 线程,那么此时就为WAITING状态

  • BLOCKED

     等待锁出现的状态:线程因为等待锁而堵塞

    比如某一操作的代码块加锁了,此时有两个线程(t1,t2)去执行该代码块,t1线程先抢到锁,进而执行代码,那么此时t2 线程则需要堵塞去等待 t1解锁,然后在进行加锁执行操作,此时 t2 在等待 t1解锁的这个时期内,t2 的状态就为BLOCKED。

    synchronized public static void fun(int x){
             try {
                 Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println(x);
        }
    
        public static void main(String[] args) {
            Thread t1 = new Thread(() -> {
                fun(1);
            });
    
            t1.start();
    
            Thread t2 = new Thread(() -> {
                fun(2);
            });
    
            t2.start();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println(t2.getState());
        }

     

    此时上述代码,在 t1线程 执行加锁代码的时候,t2线程来到锁外等待,那么 t2 线程此时的状态就为 BLOCKED

  • WAITING

堵塞等待状态:一个线程堵塞等待另一个线程,直到一个被等待的线程结束,等待的线程才能进行执行,那么此时进行堵塞等待的线程就是出于WAITING状态

注意与TIMED_WAITING进行区分

常见方法:wait方法,join(不带参数)等这些进入死等的方法都会使线程线程进入该状态

线程状态的转移

我们线程的执行是会发生变化,那么我们线程的状态也自然会根据实际情况发生变化

从new线程实例对象 —> 线程执行 —> 线程执行完毕 —> ,其中这条状态主线上会有一些其他的状态:因为各种原因触发的线程堵塞和休眠

那么让我们来进一步分析一下线程的状态之间的转移

 

根据线程执行的主线状态:NEW —> RUNNABLE —> TERMINATED;线程执行期间遇到不同的休眠堵塞情况则进入不同的状态:等待锁则为BLOCKED状态,限时等待则TIME_WAITING状态,必须等到其他线程执行完毕的等待则是WAITING状态


本篇文章介绍到这里就结束了,希望各位读者都能有所收获!

喜欢本篇文章的小伙伴能不能留下你的三连呢,在此感谢!!!

                我们下期再见!


 

 

 

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值