当前位置: 首页 > news >正文

【JAVA基础面经】线程的状态

【JAVA基础面经】线程的状态

  • 线程的基本状态
  • 线程的状态转移
  • Thread类的属性和方法
    • 构造方法
    • 属性
  • 各状态详细说明
    • NEW(新建)
    • RUNNABLE(可运行)
    • BLOCKED(阻塞)
    • WAITING(无限等待)
    • TIMED_WAITING(限期等待)
    • TERMINATED(终止)
  • 线程中断
  • 线程休眠
  • 常见面试题

线程的基本状态

通过t.getState()方法获取对应线程的状态

  • NEW状态:安排了工作还未开始行动,即Thread对象创建了但是还没有调用start()方法
  • TERMINATED状态:工作完成了,操作系统中的线程已经执行完毕销毁了,但是Thread对象还在,从而获取到的状态
  • RUNNABLE状态:可工作的,又可以分为正在工作中和即将开始工作的,也是就绪状态,处于该状态的线程在就绪队列中,随时可以被调用到CPU上执行。如果代码中没有进行sleep或其他可能导致阻塞的操作,线程即在RUNNABLE状态
  • TIMED_WAITING状态:代码中调用了 sleep 或 join 等操作就会进入到该状态,即当前线程在一定时间内是阻塞的状态,一定时间后状态解除
  • BLOCKED状态:当前线程在等待锁导致了阻塞
  • WAITING状态:当前线程在等待唤醒导致了阻塞

线程的状态转移

在 JVM 层面,RUNNABLE该状态包括:就绪(ready)和运行中(running)。线程可能在等待 CPU 时间片,也可能正在执行,他们都属于RUNNABLE状态

Thread类的属性和方法

构造方法

给线程起名字方便再调试的时候对线程进程区分,可以借助JDK中的jconsole观察线程的名字

方法说明
public Thread()创建线程对象
public Thread(Runnable target)使用Runnable对象创建线程对象
public Thread(String name)创建线程对象,并命名
public Thread(Runnable target, String name)使用Runnable对象创建线程对象,并命名

属性

属性获取方法
IDgetId()
名称getName()
状态getState()
优先级getPriority()
是否后台线程isDaemon()
是否存活isAlive()
是否被中断isInterrupted()
  • 是否后台线程 isDaemon():JVM会在一个进程的所有非后台线程结束之后才会结束执行。如果线程是后台线程,那么就不影响进程的推出,如果是前台线程,就会影响到进程的进出
  • 是否存活 isAlive():指操作系统中对应的线程是否正在运行,Thread t 只是创建了一个对象,创建 t 对象后调用t.start()才是创建了一个线程,因此t对象的生命周期和内核中线程对应的生命周期并不完全一致,run方法执行完毕后系统中的线程就销毁了,但是t对象可能还存在。start()开始之后,run()结束之前的时间内isAlive()判定为true

各状态详细说明

NEW(新建)

线程对象已创建,但未调用 start(),此时线程尚未与操作系统线程关联。

Threadt=newThread(()->System.out.println("hello"));System.out.println(t.getState());// NEW

RUNNABLE(可运行)

调用 start() 后,线程进入 RUNNABLE 状态。在 JVM 层面,该状态包括:就绪(ready)和运行中(running)。线程可能在等待 CPU 时间片,也可能正在执行。即使线程在执行 sleep 或 wait 之前的代码,也属于 RUNNABLE(未阻塞时)

Threadt=newThread(()->{for(inti=0;i<1000;i++){System.out.println(i);}});t.start();System.out.println(t.getState());// RUNNABLE(很可能)

BLOCKED(阻塞)

线程在等待获取一个 synchronized 锁时,会进入 BLOCKED 状态

Lock 接口(如 ReentrantLock)导致的等待不会进入 BLOCKED,而是 WAITING 或 TIMED_WAITING(因为 LockSupport.park())

publicclassBlockedDemo{privatestaticfinalObjectlock=newObject();publicstaticvoidmain(String[]args)throwsInterruptedException{Threadt1=newThread(()->{synchronized(lock){try{Thread.sleep(10000);}catch(InterruptedExceptione){}}});Threadt2=newThread(()->{synchronized(lock){System.out.println("获得到锁");}});t1.start();Thread.sleep(100);// 确保 t1 先获得锁t2.start();Thread.sleep(100);System.out.println(t2.getState());// BLOCKED}}

WAITING(无限等待)

线程进入等待状态,直到其他线程执行特定操作唤醒它,常见进入方式包括:

  • Object.wait()(无超时)
  • Thread.join()(无超时)
  • LockSupport.park()

唤醒方式包括:

  • Object.notify() / notifyAll()
  • join() 的线程执行完毕
  • LockSupport.unpark(thread)
publicclassWaitingDemo{publicstaticvoidmain(String[]args)throwsInterruptedException{Objectlock=newObject();Threadt=newThread(()->{synchronized(lock){try{lock.wait();}catch(InterruptedExceptione){}}});t.start();Thread.sleep(100);// 确保 t 进入 waitSystem.out.println(t.getState());// WAITING}}

TIMED_WAITING(限期等待)

与 WAITING 类似,但指定了超时时间,时间到自动返回。常见进入方式包括:

  • Thread.sleep(long millis)
  • Object.wait(long timeout)
  • Thread.join(long millis)
  • LockSupport.parkNanos()
Threadt=newThread(()->{try{Thread.sleep(5000);}catch(InterruptedExceptione){}});t.start();Thread.sleep(100);System.out.println(t.getState());// TIMED_WAITING

TERMINATED(终止)

线程 run() 方法执行完毕,或者因未捕获异常而结束。线程一旦终止,不能再次 start()(会抛出 IllegalThreadStateException)。

Threadt=newThread(()->{});t.start();t.join();// 等待结束System.out.println(t.getState());// TERMINATED

线程中断

线程休眠

常见面试题

1.sleep() 和 wait() 的区别?

区别sleep()wait()
所属Thread 类的静态方法Object 类的实例方法
是否释放锁不释放释放
唤醒方式时间到自动醒,或 interrupt()需要 notify()/notifyAll() 或超时
使用要求任何地方必须在 synchronized 块/方法内

2.BLOCKED 和 WAITING 有什么区别?

  • BLOCKED 是在等待 synchronized 锁,是被动的、由 JVM 管理。
  • WAITING 是主动调用 wait()、join() 等方法进入,等待其他线程显式唤醒,通常与锁配合(wait 必须持有锁)。

3.线程终止后能否再次启动?

不能。start() 方法只能调用一次,再次调用会抛出 IllegalThreadStateException。

3.notify 和 notifyAll 的区别?


(待更新)

http://www.jsqmd.com/news/631115/

相关文章:

  • 【44】软考软件设计师——高频考点速记手册|100个核心概念+公式+模板 便携速记卡
  • 【2026年最新600套毕设项目分享】微信小程序的电子竞技信息交流平台(30038)
  • 告别网络依赖!手把手教你用ISO镜像在CentOS 8上搭建本地DNF软件仓库
  • OPUS编解码器在audio DSP上的移植和应用此
  • 硬件加速与 OMX/Codec2:解密编解码器的底层世界
  • [AI/应用/MCP] MCP Server/Tool 开发指南韧
  • 【OpenClaw企业级智能体实战】第29篇:边缘智能:在10美元开发板上跑OpenClaw(PicoClaw实战)
  • 从Simulink到LabVIEW:VeriStand联合仿真中人机交互界面的高效构建与数据联动
  • 【2026年最新600套毕设项目分享】外籍人员管理系统微信小程序(30039)
  • CiteSpace 6.3.R1 从零到一:基于CNKI数据的科研图谱实战指南
  • FastAPI子应用挂载:别再让root_path坑你一夜邑
  • 世界第一个开源可商用 .NET Office 转 PDF 工具/库 - MiniPdf圃
  • 5分钟掌握抖音批量下载完整指南:从零到精通的效率革命
  • 锐捷交换机连接与故障排除实战指南
  • OpenClaw+优云智算Coding Plan:从灵感到成文,再到发布的全流程AI自动化仲
  • Qwen3-14B大模型技术解析:从架构原理到私有化部署实践
  • 【2026年最新600套毕设项目分享】微信小程序的绘画学习平台(30040)
  • 【OpenClaw从入门到精通】第60篇:多智能体协同实战——用“龙虾”搭建你的数字员工团队(2026企业版)
  • 一文学习 工作流开发 BPMN、 Flowable账
  • 3分钟上手:告别音频分割的繁琐,让AI帮你自动切分
  • 打字不如说话,说话不如截图——AI 代码助手的多模态输入实践以
  • MPNN框架 消息生成与聚合 (公式 1)
  • Android 4G上网协议解析:从PPP建立到数据传输全流程
  • AD9268/AD9643硬件调试避坑实录:从SPI配置到LVDS信号,我们踩了这些坑
  • OpenCode与OhMyOpenCode使用指南
  • 【Leet Code 】滑动窗口
  • 聊一聊 C# 中的闭包陷阱:foreach 循环的坑你还记得吗?樟
  • 零基础网页数据抓取实战:Web Scraper Chrome扩展一站式入门指南
  • STM32 NVIC优先级设置详解:以红外传感器计数为例
  • 骨架动作识别新突破:CTR-GCN的通道拓扑优化策略解析