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

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

  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()`方法,或者线程被中断。

总结区别:

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

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

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

相关推荐
AI人工智能+电脑小能手22 分钟前
【大白话说Java面试题 第65题】【JVM篇】第25题:谈谈对 OOM 的认识
java·开发语言·jvm
阿维的博客日记1 小时前
Nacos 为什么能让配置动态生效?(涉及 @RefreshScope 注解)
java·spring
雨辰AI1 小时前
SpringBoot3 + 人大金仓读写分离 + 分库分表 + 集群高可用 全栈实战
java·数据库·mysql·政务
Patrick_Wilson1 小时前
知识沉淀的四层模型:从个人笔记到企业资产,让文档真正长出复利
面试·程序员·ai编程
辰海Coding2 小时前
MiniSpring框架学习-完成的 IoC 容器
java·spring boot·学习·架构
橙序员小站2 小时前
人人都在鼓吹的OPC,我想给你泼盆冷水
面试·创业
小小编程路2 小时前
C++ 多线程与并发
java·jvm·c++
AI视觉网奇2 小时前
linux 检索库 判断库是否支持
java·linux·服务器
她的男孩3 小时前
从零搭一个企业后台,为什么我把能力拆成 Starter 和 Plugin
java·后端·架构
RainCity3 小时前
Java Swing 自定义组件库分享(七)
java·笔记·后端