【Java多线程】线程状态

Java线程状态

1.1 Java线程状态概述

我们可以通过Java内部提供的枚举类型Thread.State,查看所有的Java线程状态

public class ThreadDemo16 {
    public static void main(String[] args) {
        for (Thread.State state : Thread.State.values()) {
            System.out.println(state);
        }
    }
}

打印结果如下图所示:

在这里插入图片描述

  • NEW:表示线程处于新建状态,但是仍未开始执行任务(调用start方法之前)
  • RUNNABLE:表示线程处于已就绪状态,此时线程正处于CPU上调度或者可以随时被CPU调度
  • BLOCKED:表示当前线程由于锁竞争处于阻塞等待状态
  • WAITING:表示当前线程处于阻塞等待状态
  • TIMED_WATING:表示当前线程处于带有时限的阻塞等待状态(超时等待)
  • TERMINATED:表示当前线程任务完成,处于终止状态(run方法执行完毕)

1.2 Java线程状态图

在这里插入图片描述

上图描述的就是Java中的线程状态模型,可以概括线程的生命周期。下面我们举一个生动形象的生活案例来解释每个状态所表示的含义:

考虑这样一个场景:中午到了饭点了,你和大伙一起去食堂吃饭。这时每一个窗口都只有一位食堂阿姨为同学们打饭,你到达你最喜欢的烤肉饭窗口发现前方已经有很多同学都在排队了,礼貌懂事的你自觉的到队列尾部进行排队。此时就是一个多线程模型,下面将解释此背景中各种状况及对应的线程状态。

  • NEW:你此时正处于前往食堂的路上,你知道自己要去吃饭,但是并不能立马吃上(已经分配任务,但是无法被CPU调度)
  • RUNNABLE:此时你羡慕的望着队头正在点菜的同学,这个线程可以或是正在被CPU调度(处于就绪状态)
  • TIME_WAITED | WAITED:此时饭菜卖完了,后勤正在进行补给当中,同学们需要进行等待(阻塞等待状态)
  • BLOCKED:排队过程中,你看到有两位同学因为竞争一双筷子起了冲突,此时筷子可以看作锁对象,持有筷子的一方就是持有锁对象,另一方由于锁冲突需要阻塞等待(锁冲突导致的阻塞等待)
  • TERMINATED:最后的最后,你终于吃上你心爱的烤肉饭了,此时你吃饭的任务已经完成(处于终止状态)

1.3 观察线程状态的切换

1.3.1 观察NEW、RUNNABLE、TERMINATED状态切换

  • 使用getState方法获取线程的运行状态

    public class ThreadDemo18 {
        public static void main(String[] args) throws InterruptedException {
            Thread t = new Thread(() -> {
                System.out.println("当前t线程状态:" + Thread.currentThread().getState());
            });
            System.out.println("当前t线程状态:" + t.getState());
            t.start();
            t.join();
            System.out.println("当前t线程状态:" + t.getState());
        }
    }
    

    在这里插入图片描述

1.3.2 观察WAITING、TIMED_WAITING、BLOCKED状态切换

  • 通过jconsole工具获取线程状态

    public class ThreadDemo19 {
    
        private static Object obj = new Object();
        public static void main(String[] args) {
            Thread t1 = new Thread(() -> {
                synchronized (obj) {
                    while (true) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
            t1.start();
            Thread t2 = new Thread(() -> {
               synchronized (obj) {
                   System.out.println("我好想要执行...");
               }
            });
            t2.start();
        }
    }
    

    通过jconsole工具可以查看线程此时的状态:Thread-0处于超时等待状态,Thread-1处于BLOCKED状态

    这是因为线程Thread-0先被执行并且进入synchronized代码块中,获得锁对象并调用Thread.sleep(long millis)方法处于线程休眠超时等待状态,线程Thread-1由于争夺同一个锁对象,但是此时锁对象被Thread-0获取,处于BLOCKED状态

    在这里插入图片描述
    在这里插入图片描述

    如果将代码稍加修改,让Thread-0中执行sleep(long millis)方法改成wait()此时线程Thread-0的状态就是WAITING状态:

    在这里插入图片描述

    此时Thread-0线程执行wait()方法后做了以下三件事:①、释放当前锁 ②、处于阻塞等待状态 ③、直到别的线程唤醒则继续执行。但是没有别的线程唤醒该线程于是一直处于WAITING状态。

  • 小节:

    1. BLOCKED 表示等待获取锁, WAITING 和 TIMED_WAITING 表示等待其他线程发来通知.
    2. TIMED_WAITING 线程在等待唤醒,但设置了时限; WAITING 线程在无限等待唤醒
  • 27
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值