线程的五种状态&六种状态

302 阅读3分钟

线程的五种状态&六种状态

一.线程的五种状态

线程的五种状态是从操作系统的层面进行划分的

image.png

  1. 初始状态

    线程被创建后还没有调用.start()方法的状态就是

  2. 就绪状态

    线程调用了start()方法,此时可以被cpu分配时间片运行

  3. 运行状态

    运行中的线程就处于运行状态

  4. 阻塞状态

    1. 与就绪状态一样不处于运行状态,但是处于阻塞状态下的线程不可以被cpu分配时间片。而处于就绪状态的线程可以被cpu分配时间片。
    2. 如果是调用了阻塞API,如读写文件时,此时实际上线程没有使用到CPU,会导致线程上下文的切换,进入到阻塞状态
    3. 操作系统中阻塞状态对应Java中线程的TIMED_WAITING,WAITING,BLOCKED三种状态
  5. 终止状态

    终止状态就是线程的生命周期结束了,也就是线程已经执行完毕了。已经终止的线程不会再转换为其他状态


二.线程的六种状态

线程的六种状态是从Java中Thread类的枚举State进行划分的

image.png

六种状态分别是

  1. NEW(新建)
  2. RUNNABLE(可运行的)
  3. BLOCKED(阻塞)
  4. WAITING(等待)
  5. TIMED_WAITING(超时等待)
  6. TERMINATED(终止)

以下是对六种状态的解释及代码演示

  1. NEW

    与上面相同,当线程创建后但并未调用其start()方法之前都处于NEW的状态

    Thread thread = new Thread(
            () -> {
    
            }
    );
    System.out.println(thread.getState());
    
  2. RUNNABLE

    在Java中,正在运行的线程和处于就绪状态的线程都是RUNNABLE状态

    Thread thread = new Thread(
            () -> {
    
            }
    );
    thread.start();
    System.out.println(thread.getState());
    
  3. TIMED_WAITING

    当线程调用sleep方法时或者调用join方法并传入等待时间时就会进入TIMED_WAITING的状态,这个状态标识线程处于等待之中,且有具体的一个等待时间

    Thread t3 = new Thread(
            () -> {
                try {
                    Thread.sleep(100000); // 长时间sleep
                    System.out.println(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
    );
    t3.start();
    Thread.sleep(50); //这里让主线程休眠一会,保证t3线程执行到休眠处
    System.out.println("t3 state:" + t3.getState()); //TIMED_WAITING
    
  4. WAITING

    当线程调用join方法但没有指定等待的时间的时候,线程就进入了一个WAITING状态,该状态表示线程处于等待过程之中,且没有指定等待的时间。该状态不能被CPU分配时间片。

    Thread t4 = new Thread(
            () -> {
                try {
                    t3.join();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
    );
    t4.start(); 
    Thread.sleep(50);
    System.out.println("t4 state:" + t4.getState());//WAITING
    
  5. BLOCKED

    当两个线程对同一个对象加锁,获取锁失败的线程会进入到一个BLOCKED即阻塞的一个状态,这个状态下线程需要等待另一个线程释放锁才能恢复。

    Thread lock = new Thread(
            () -> {
                synchronized (demo6.class) {
                    try {
                        Thread.sleep(100000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
    );
    lock.start();
    Thread t5 = new Thread(
            () -> {
                synchronized (demo6.class) {
                    try {
                        Thread.sleep(100000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
    );
    t5.start();
    Thread.sleep(50);
    System.out.println("t5 state:" + t5.getState() ); //BLOCKED
    
  6. TERMINATED

    线程执行完毕,生命周期结束后就进入了TERMINATED状态,不能从这个状态恢复到其他状态。

    Thread t6 = new Thread(() -> {
        int i = 0;
    });
    t6.start();
    Thread.sleep(50);
    System.out.println("t6 state:" + t6.getState());