美文网首页
线程的生命周期

线程的生命周期

作者: Travis_Wu | 来源:发表于2020-12-05 19:30 被阅读0次

    线程的生命周期和状态

    状态名称 说明
    New 新创建
    Runnable 可运行
    Blocked 被阻塞
    Waiting 等待
    Timed_waiting 计时等待
    Terminated 被终止
    • New 表示线程被创建但尚未启动的状态
      当我们用 new Thread() 新建一个线程时,如果线程没有开始运行 start() 方法,所以也没有开始执行 run() 方法里面的代码,那么此时它的状态就是 New ,而一旦线程调用了 start() 它的状态就会从 New 变成 Runnable
    • Runnable 可运行
      Java 中的 Runable 状态对应操作系统线程状态中的两种状态,分别是 Running 和 Ready
      Java 中处于 Runnable 状态的线程有可能正在执行,也有可能没有正在执行正在等待被分配 CPU 资源
    • 阻塞状态
      • Blocked(被阻塞)
        1. 从 Runnable 状态进入 Blocked 状态只有一种可能,就是进入 synchronized 保护的代码时没有抢到 monitor 锁 无论是进入 synchronized 代码块 还是 synchronized 方法,都是一样
        2. 从 Blocked 状态进入 Runnable 状态 要求线程获取 monitor 锁
      • Waiting(等待)
        • 线程进入 Waiting 状态有三种可能性:
          1. 没有设置 Timeout 参数的 Object.wait() 方法
          2. 没有设置 Timeout 参数的 Thread.join() 方法
          3. LockSupport.park() 方法
        • 从 Waiting 状态流转到其他状态则比较特殊
          如果其他线程调用 notify() 或 notifyAll()来唤醒它它会直接进入 Blocked 状态 因为唤醒 Waiting 线程的线程如果调用 notify() 或 notifyAll(),要求必须首先持有该 monitor 锁,所以处于 Waiting 状态的线程被唤醒时拿不 到该锁,就会进入 Blocked 状态
      • Timed Waiting(计时等待)
        • 线程进入 Timed Waiting 状态有四种可能性:
          1. 设置了时间参数的 Thread.sleep(long millis) 方 法
          2. 设置了时间参数的 Object.wait(long timeout) 方 法
          3. 设置了时间参数的 Thread.join(long millis) 方 法
          4. 设置了时间参数的 LockSupport.parkNanos(long nanos) 方法和LockSupport.parkUntil(long deadline) 方法
        • Timed Waiting 中执行 notify() 和 notifyAll() 也是一样的道理
          1. 如果其他线程调用 notify() 或 notifyAll()来唤 醒它它会直接进入 Blocked 状态
          2. 如果它的超时时间到了且能直接获取到锁/join的线程运行结束/被中断/调用了LockSupport.unpark(),会直接恢复到 Runnable 状态,而无需经历 Blocked 状态
      • Terminated 终止
        • 进入Terminated 终止状态有两种可能:
          1. run() 方法执行完毕,线程正常退出
          2. 出现一个没有捕获的异常,终止了 run() 方法,最终导致意外终止

    注意点

    1. 线程的状态是需要按照箭头方向来走的,比如线程从 New 状态是不可以直接进入 Blocked 状态的,它需要先经历 Runnable 状态
    2. 线程生命周期不可逆:一旦进入 Runnable 状态就不能回到 New 状态;一旦被终止就不可能 再有任何状态的变化。所以一个线程只能有一次 New 和 Terminated 状态,只有处于中间状 态才可以相互转换

    wait/notify和sleep的异同

    • 相同点:
      1. 它们都可以让线程阻塞
      2. 它们都可以响应 interrupt 中断,在等待的过程中如果收到中断信号,都可以进行响应, 并抛出 InterruptedException 异常
    • 不同点:
      1. wait 方法必须在 synchronized 保护的代码中使用,而 sleep 方法并没有这个要求
      2. 在同步代码中执行 sleep 方法时,并不会释放 monitor 锁,但执行 wait 方法时会主动 释放 monitor 锁
      3. sleep 方法中会要求必须定义一个时间,时间到期后会主动恢复,而对于没有参数的 wait 方法而言,意味着永久等待,直到被中断或被唤醒才能恢复,它并不会主动恢复
      4. wait/notify 是 Object 类的方法,而 sleep 是 Thread 类的方法

    相关文章

      网友评论

          本文标题:线程的生命周期

          本文链接:https://www.haomeiwen.com/subject/knogwktx.html