Java EE - 线程的状态

目录

1.NEW状态

未开启或者即将开启线程的的状态就是NEW状态 ,可以通过Thread函数中的getState方法获取当前线程的状态。

java 复制代码
public class ThreadState {

    //NEW状态
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
          
        });
        //线程还未开启
        System.out.println(t.getState());
    }
}

2.RUNNABLE状态

线程正在运行的状态就是RUNNABLE状态。

java 复制代码
public class ThreadState {

    //RUNNABLE状态
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                ///
            }
        });
        //开启线程
        t.start();
        //获取线程状态
        System.out.println(t.getState());
    }
}

3.TIMED_WAITING状态

当线程进入有限时间的阻塞等待就进入了TIME_WARNING状态。

java 复制代码
public class ThreadState {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 10; i++) {//循环10次
                try {
                    Thread.sleep(100);//休眠0.1秒
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        //开启线程
        t.start();
        //使main线程进入休眠500毫秒
        Thread.sleep(500);
        //t线程需要休眠1000毫秒,程序执行导致t线程还是在有限时间的休眠中
        System.out.println(t.getState());
    }
}

4.WAITING状态

线程进入无限制时间的等待就是warning状态,线程进入warning状态通常是线程进入阻塞状态,或者,线程中使用了wait方法,需要等待notify方法的唤醒。

java 复制代码
public class ThreadState {
  public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        
        t.start();
        t.join();//让main线程等待t线程结束,t线性一直循环休眠,
                 //因此mian线程无法结束,一直进入warning状态
        
    }
}

以上程序中main线程的状态可以在程序运行后,打开jconsole查看,jconsole默认存放路径为

C:\Program Files\Java\jdk-17\bin,在bin目录下打开jconsole;





可以观察到main线程 进入waiting状态,一直处于阻塞中,但是一般程序处于WAITING的阻塞状态是使用wait和notify搭配使用,两个方法都是Object类中提供的,所以所有的类都可以使用wait和notify方法,以下用wait方法使线程处于WAITING状态。

java 复制代码
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
                try {
                    Thread.currentThread().wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

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

运行程序发现会报异常,这是因为wait方法的使用需要搭配锁没有锁会抛出非法监视异常 ,所以可以给当前线程对象加锁,使用关键字synchronize,需要搭配一个参数,即锁对象,大括号内是加锁的内容。

java 复制代码
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            //加锁,加锁的对象是t
            synchronized (Thread.currentThread()) {
             //加锁的内容
                try {
                    Thread.currentThread().wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }//解锁
        });
        t.start();
        Thread.sleep(100);//确保已经加锁
        System.out.println(t.getState());//获取线程状态
    }

5.Blocking状态

Blocking状态即阻塞状态,同时再两个线程同时申请各自加锁的对象导致的状态,例如:线程t1已经加锁了o1对象,线程t2加锁了o2对象,此时t1线程申请再加锁o2对象,t2线程再申请加锁o1对象,由于两个线程都已加锁并未解锁,申请新的锁对象就会一直处于阻塞状态中,t1和t2线程的状态都为Blocking状态。

java 复制代码
 public static void main(String[] args) {
        Object o1 = new Object();//对象o1
        Object o2 = new Object();//对象o2
        Thread t1 = new Thread(() -> {
            //获取锁1
            synchronized (o1){
                try {
                    Thread.sleep(1);//确保t2线程可以获得o2对象
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                //获取锁2
                synchronized (o2){

                }
            }
        });
        Thread t2 = new Thread(() -> {
            //获取锁2
           synchronized (o2){
               //获取锁1
               synchronized (o1){

               }
           }
        });
        //启动线程
        t1.start();
        t2.start();
    }


程序运行后可以观察到t1线程(Thread-0系统默认命名)处于阻塞等待的状态,是由于申请的加锁对象已经被加锁;t2线程(Thrad-1)也处于Blocking状态,原因是申请加锁的对象被t1线程加锁。

6.TERMINATED状态

线程结束 时,获取线程的状态就是terminated状态

java 复制代码
public class ThreadState {
  public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() ->{

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

7.小结

通过以上介绍可以了解到线程的状态主要有六种:

NEW,RUNNABLE,TIMED_WAITING,WAITING,BOLCKING,TERMINATED

NEW状态 是表示线程在启动前的状态 ,当线程启动并正常运行 时就进入了RUNNABLE状态 ,当线程需要停止运行一段有限的时间 就进入了TIME_WAITING状态 ,如果需要一直等待 ,在被其它线程唤醒(notify方法唤醒)前的状态就是WAITING状态 ,当线程终止 时,线程状态为TERMINATED

希望这篇关于线程状态的文章能帮助你理清相关概念。如果内容对你有启发或解决了疑惑,不妨点个赞支持一下。

关于线程的更多深入探讨,比如线程同步或死锁问题,将在后续文章中展开。欢迎持续关注,下篇再见!

若有任何疑问或建议,也欢迎在评论区留言交流。

相关推荐
拾忆,想起2 小时前
超时重传 vs 快速重传:TCP双保险如何拯救网络丢包?
java·开发语言·网络·数据库·网络协议·tcp/ip·php
budingxiaomoli2 小时前
多线程(一)
java·开发语言·jvm·java-ee
Yue丶越2 小时前
【C语言】深入理解指针(二)
c语言·开发语言·数据结构·算法·排序算法
兜有米啦3 小时前
python练习题3
开发语言·python
Wzx1980123 小时前
go基础语法练习
开发语言·后端·golang
忧郁的蛋~3 小时前
.NET异步编程中内存泄漏的终极解决方案
开发语言·前端·javascript·.net
2301_795167203 小时前
玩转Rust高级应用. ToOwned trait 提供的是一种更“泛化”的Clone 的功能,Clone一般是从&T类型变量创造一个新的T类型变量
开发语言·后端·rust
你才是向阳花4 小时前
如何用Python实现飞机大战小游戏
开发语言·python·pygame
合作小小程序员小小店4 小时前
web网页开发,在线%商城,电商,商品购买%系统demo,基于vscode,apache,html,css,jquery,php,mysql数据库
开发语言·前端·数据库·mysql·html·php·电商