zoukankan      html  css  js  c++  java
  • Java基础教程:多线程基础——线程的状态

    Java基础教程:多线程基础——线程的状态

    线程的状态

      在Java中,线程有6种状态,分别为:

    • 初始:NEW
    • 运行:RUNNABLE
    • 阻塞:BLOCKED
    • 等待:WAITING
    • 超时等待:TIMED_WAIT
    • 终止:TERMINAL

      这六种状态分别对应于Thread.State中的枚举类型。可以用下面这张图来解释一下Java中的线程的状态转换

      

    初始态

      初始态表示一个线程刚被初始化,即new Thread()

    Thread thread = new Thread();
    System.out.println(thread.getState());
    
    //Output:NEW
    

      这个没什么好说的,也是最简单。

    运行态

      当调用一个Thread对象的start方法后,该线程进入运行态。运行态的名字是很有迷惑性的,其实运行态再细分还可以分为两个子状态:

    • Ready:调用start后,该线程放入可运行线程池中,等待被调度,获得CPU运行权
    • Running:获得CPU时间片后变为运行中状态

      也即是就绪和运行中都是运行态,一定要谨记!

    阻塞态

      阻塞态可能理解就要上一个台阶了,阻塞态表示一个线程因为等待临界区的锁而被阻塞产生的状态。我们举一个例子,我们有一个上锁的单人厕所,有两个人同时要求上厕所,但是有一个人抢先进去了,然后反锁了,第二个就在厕所门口等着,他就属于阻塞态。此时又来了第三个人、第四个等等,他们都属于阻塞态,只有第一个出来,下一个进去的才能摆脱这个状态!

      话不多说,我们写代码来实现这情形,在这里用了Lambda表达式来简写线程的run方法。

    public class BlockedDemo {
        public static void main(String[] args) throws InterruptedException {
            Toilet room = new Toilet();
            Thread a = new Thread(() -> room.use());
            a.start();
            Thread.sleep(1000);
            Thread b = new Thread(() -> room.use());
            b.start();
            Thread.sleep(2000);
            System.out.println(b.getState());
        }
    
    }
    
    class Toilet{
        synchronized void use(){
            try {
                Thread.sleep(7000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

      此时打印出来的状态就是:BLOCKED状态!

    等待态与超时等待态

      当我们拿到锁执行方法的时候,我们可能由于某些原因,还是以厕所为例,发现没带纸,我们需要出去,这时肯定不能霸占厕所,所以我们要主动出去,遂调用wait方法后,让出锁,我们就处于等待状态。如果送纸的人来了,再把我们唤醒notify。

    public class WaitingDemo {
        public static void main(String[] args) throws InterruptedException {
            WaitToilet room = new WaitToilet();
            Thread a = new Thread(() -> room.use());
            a.start();
            Thread.sleep(100);
            System.out.println(a.getState());
        }
    
    }
    
    class WaitToilet{
        synchronized void use(){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

      你可以看到wait(long time)有一个参数指定时间,表示我们先出去等time时间,然后再排队如厕,此时我们就处于超时等待状态。如果送纸的人迟迟不来,也不等了,

    我们再来简单总结一下:

    • 一个线程A在拿到锁但不满足执行条件的时候,需要另一个线程B去满足这个条件,那么线程A就会释放锁并处于waiting的状态,等线程B执行完再执行。
    • waiting状态的好处是:此状态的线程不再活动,不再参与调度,因此不会浪费 CPU 资源,也不会去竞争锁了,相比暴力的blocking状态,要优雅很多
    • 如果设置等待时间的话,超过时间,会自动被唤醒

    终止状态

      线程所有逻辑执行完了,就处于终止状态。这个和初始态一样都是好理解的!

  • 相关阅读:
    求数组中的最小子数组,时间复杂度o(n),java
    第四周进度条
    四则混合运算3
    软件工程作业3
    《构建之法》第三周阅读笔记
    第三周学习进度
    学习进度01
    构建之法阅读笔记01
    构建之法问题
    随机生成题目运算
  • 原文地址:https://www.cnblogs.com/MrSaver/p/12398951.html
Copyright © 2011-2022 走看看