Java多线程:线程状态

    技术2024-11-02  25

    # 面试题

    Java中线程有哪几种状态,线程的生命周期。

    每个状态的含义。

    状态之间的转化过程以及触发条件,图示。

    # 线程有哪几种状态

    Java doc

    image.png

    New (刚创建出线程实例)

    new Thread()

    Runnable (可运行/运行状态,等待CPU的调度)(要注意:即使是正在运行的线程,状态也是Runnable,而不是Running)

    调用了thread.start()启动线程。

    被synchronized标记的代码,获取到同步监视器。

    obj.notify()唤醒线程。

    obj.notifyAll()唤醒线程。

    obj.wait(time), thread.join(time)等待时间time耗尽。

    Blocked (阻塞状态)

    运行被synchronized标记的代码且未获取到同步监视器。

    Waiting (不超时等待状态)

    threadA中调用threadB.join(),threadA将Waiting,直到threadB终止。

    obj.wait() 释放同步监视器obj,并进入阻塞状态。

    TimedWaiting (等待指定时间time)。

    threadA中调用threadB.join(time)。

    obj.wait(time)

    sleep(time)。

    Terminated (线程终止)

    线程正常执行完毕。

    发生了未捕获的异常。

    # 注意

    由于wait()/wait(time)导致线程处于Waiting/TimedWaiting状态,当线程被notify()/notifyAll()/wait等待时间到之后,如果没有获取到同步监视器。会直接进入Blocked阻塞状态。

    # 线程状态转换图示

    image.png

    # 代码演示

    New/Runnable/Terminated

    /**  * 线程的状态演示:NEW,Runnable,Terminated  *  * @author futao  * @date 2020/6/7  */ public class NewRunnableTerminated implements Runnable {     @Override     public void run() {         for (int i = 0; i < 1000; i++) {             System.out.println(i);         }     }     public static void main(String[] args) throws InterruptedException {         Thread thread = new Thread(new NewRunnableTerminated());         System.out.println("因为还未调用start(),所以预期`New`:" + thread.getState());         thread.start();         //等待子线程跑一会,看看运行中的状态是不是Runnable         Thread.sleep(10L);         System.out.println("线程start()之后,预期Runnable:" + thread.getState());         //等待子线程执行完毕,再查看其状态         Thread.sleep(1000L);         System.out.println("线程任务执行完毕,预期Terminated:" + thread.getState());     } }

    结果

    image.png

    image.png

    image.png

    Blocked,Waiting,TimedWaiting

    /**  * 演示Blocked,Waiting,TimedWaiting  *  * @author futao  * @date 2020/6/7  */ public class BlockedWaitingTimedWaiting implements Runnable {     @Override     public void run() {         try {             sync();         } catch (InterruptedException e) {             e.printStackTrace();         }     }     /**      * 同步方法      *      * @throws InterruptedException      */     public synchronized void sync() throws InterruptedException {         Thread.sleep(1000L);         wait();     }     public static void main(String[] args) throws InterruptedException {         BlockedWaitingTimedWaiting blockedWaitingTimedWaiting = new BlockedWaitingTimedWaiting();         Thread thread1 = new Thread(blockedWaitingTimedWaiting);         Thread thread2 = new Thread(blockedWaitingTimedWaiting);         thread1.start();         //为了尽可能让thread1先执行,获取到同步方法的锁         Thread.sleep(10L);         thread2.start();         Thread.sleep(500L);         System.out.println("因为thread1处于sleep(time)状态,所以预期线程状态为<TimedWaiting>: " + thread1.getState());         System.out.println("因为sync()方法的锁被thread1持有,所以thread2被阻塞,预期状态为<Blocked>: " + thread2.getState());         //等待thread1的sleep(time)时间结束,进入wait()方法         Thread.sleep(1000L);         System.out.println("因为thread1的sleep(time)时间结束,进入wait()方法,所以预期thread1的线程状态为<Waiting>:" + thread1.getState());     } }
    Processed: 0.009, SQL: 9