线程的生命周期及状态转换

线程的生命周期指的是从创建到结束的整个过程,包括线程的创建、运行、阻塞、唤醒、等待、终止等状态。在不同的编程语言和操作系统中,线程的状态和状态转换可能略有不同,但基本的概念是相似的。以下是线程生命周期中常见的状态及其转换:

  1. **新建(New)**:
  • 线程被创建,但还没有开始运行。在这个阶段,线程已经被分配了必要的资源,如内存空间等,但还没有被调度执行。
  1. **就绪(Runnable)**:
  • 线程已经准备好运行,它已经获得了除CPU以外的所有必要资源,正在等待CPU时间片以便执行。在这个阶段,线程可能在运行,也可能在就绪队列中等待。
  1. **运行(Running)**:
  • 线程正在执行。在单核处理器上,同一时刻只能有一个线程处于运行状态;在多核处理器上,可以有多个线程同时运行。
  1. **阻塞(Blocked)**:
  • 线程正在等待一个监视器锁(例如,等待一个同步块或方法释放锁)或其他资源,因此不能继续执行。在这个阶段,线程不会占用CPU时间。
  1. **等待(Waiting)**:
  • 线程通过调用`wait()`方法进入等待状态,它释放了对象的锁,并等待其他线程调用相同对象的`notify()`或`notifyAll()`方法。在等待状态中,线程不会去竞争CPU资源,也不能被中断。
  1. **超时等待(Timed Waiting)**:
  • 线程在指定的时间段内等待,例如通过调用`wait(long timeout)`、`sleep(long millis)`、`join(long millis)`等方法。超时后,线程会自动转换回就绪状态。
  1. **终止(Terminated)**:
  • 线程执行完毕或因为某种原因被强制终止。在这个阶段,线程释放了所有资源,并从系统中彻底消失。

状态转换如下:

  • **新建 -> 就绪**:当线程被创建后,它会被放入就绪队列等待调度。

  • **就绪 -> 运行**:当线程获得CPU时间片时,它从就绪状态转换到运行状态。

  • **运行 -> 阻塞**:当线程请求一个已经被其他线程占用的资源时,它会被阻塞。

  • **运行 -> 等待**:当线程调用`wait()`方法时,它会释放对象锁并进入等待状态。

  • **等待 -> 就绪**:当其他线程调用`notify()`或`notifyAll()`方法时,等待状态的线程可能会被唤醒,并转换回就绪状态。

  • **超时等待 -> 就绪**:如果在指定的超时时间内没有被唤醒,线程会自动从超时等待状态转换回就绪状态。

  • **运行/阻塞/等待 -> 终止**:当线程执行完毕或被中断导致异常退出时,它会从任何状态转换到终止状态。

请注意,具体的线程状态和转换可能会根据具体的编程环境和操作系统有所不同。

在线程状态转换中,"阻塞"(Blocked)和"等待"(Waiting)是两种不同的状态,它们的主要区别在于线程的行为和原因:

  1. **阻塞(Blocked)**:
  • **原因**:线程被阻塞通常是因为它正在尝试获取一个已经被其他线程占用的同步资源(如锁)。在这种情况下,线程必须等待直到它能够获得该资源。

  • **行为**:阻塞状态的线程不会释放对象的锁,它在等待获取锁的同时,不会做任何其他事情,也不会被CPU调度执行。

  • **唤醒**:线程从阻塞状态被唤醒通常是由其他线程释放了锁,并且线程调度器决定将该线程调度到运行状态。

  1. **等待(Waiting)**:
  • **原因**:线程进入等待状态通常是因为它调用了某些特定的方法,如`wait()`、`join()`或`LockSupport.park()`,这些方法会使线程主动放弃对象的锁并进入等待状态,直到被显式地唤醒。

  • **行为**:处于等待状态的线程不会去尝试获取任何锁,它们被挂起,直到被其他线程通过调用`notify()`、`notifyAll()`、`interrupt()`或`LockSupport.unpark()`等方法唤醒。

  • **唤醒**:线程从等待状态被唤醒需要外部的干预,比如其他线程调用了`notify()`或`notifyAll()`方法,或者线程被中断。

总结区别:

  • **阻塞**是线程因为竞争资源而被动进入的状态,它在等待获取资源的同时不会释放锁。

  • **等待**是线程通过调用特定的方法主动进入的状态,它在等待被唤醒的同时会释放锁。

这两种状态的主要区别在于线程是否主动放弃锁以及它们被唤醒的方式。阻塞状态的线程需要外部资源的释放来被唤醒,而等待状态的线程则需要其他线程的显式唤醒操作。

相关推荐
liuyuzhongcc几秒前
List 接口中的 sort 和 forEach 方法
java·数据结构·python·list
五月茶4 分钟前
Spring MVC
java·spring·mvc
sjsjsbbsbsn14 分钟前
Spring Boot定时任务原理
java·spring boot·后端
yqcoder15 分钟前
Express + MongoDB 实现在筛选时间段中用户名的模糊查询
java·前端·javascript
菜鸟蹦迪43 分钟前
八股文实战之JUC:ArrayList不安全性
java
2501_9032386543 分钟前
Spring MVC配置与自定义的深度解析
java·spring·mvc·个人开发
逻各斯1 小时前
redis中的Lua脚本,redis的事务机制
java·redis·lua
计算机毕设指导61 小时前
基于Springboot学生宿舍水电信息管理系统【附源码】
java·spring boot·后端·mysql·spring·tomcat·maven
计算机-秋大田1 小时前
基于Spring Boot的兴顺物流管理系统设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·spring·课程设计
计算机小白一个1 小时前
蓝桥杯 Java B 组之背包问题、最长递增子序列(LIS)
java·数据结构·蓝桥杯