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

孤舟笔记 并发篇十八 为什么启动线程不能直接调用run()方法?调用两次start()又会怎样?这个设计藏着大智慧

文章目录一、先说结论run() 和 start() 的核心区别二、直接调用 run()根本没有新线程start() 源码做了什么三、调两次 start()直接报错四、正确姿势需要新线程就创建新对象五、Thread 的状态机为什么只能 start 一次run() vs start() 全景回答技巧与点评标准回答加分回答面试官点评个人网站新手写多线程最容易犯两个错一是直接调run()而不是start()二是同一个线程对象调两次start()。前者线程根本没启动后者直接抛异常。但你有没有想过为什么 Java 要这么设计搞懂了这两个问题你对线程生命周期的理解就跨过了会用的门槛。一、先说结论run() 和 start() 的核心区别维度start()run()作用启动新线程由 JVM 调用 run()在当前线程中执行 run() 方法体是否创建新线程✅ 是❌ 否调用次数只能调一次可以反复调重复调用抛 IllegalThreadStateException正常执行底层机制native start0() 创建 OS 线程普通方法调用一句话记住start() 是开工仪式run() 是工作内容——仪式只能搞一次但活可以反复干。二、直接调用 run()根本没有新线程ThreadtnewThread(()-{System.out.println(当前线程: Thread.currentThread().getName());});t.run();// 输出当前线程: main 在主线程执行的t.start();// 输出当前线程: Thread-0 这才是新线程调 run() 就像你叫了一个外卖但没下单没 start自己跑去店里吃了——外卖员新线程根本没出动。调 start() 就像你正式下了单外卖员出发送货——新线程启动了run() 会在新线程中被 JVM 自动调用。start() 源码做了什么publicsynchronizedvoidstart(){if(threadStatus!0)// 状态检查 thrownewIllegalThreadStateException();group.add(this);start0();// native 方法创建 OS 线程 }privatenativevoidstart0();// JVM 实现真正创建线程关键流程start() 调用 native start0() → JVM 创建操作系统线程 → 新线程执行 run()。直接调 run() 绕过了这整条链路只是普通方法调用。三、调两次 start()直接报错ThreadtnewThread(task);t.start();// 正常启动t.start();// IllegalThreadStateException 看看源码为什么报错publicsynchronizedvoidstart(){if(threadStatus!0)// 已经启动过threadStatus ! 0 thrownewIllegalThreadStateException();...}为什么不让调两次因为线程的生命周期是单向的NEW → RUNNABLE → (BLOCKED/WAITING/TIMED_WAITING) → TERMINATED线程一旦启动就回不到 NEW 状态。你没法让一个已经跑完的线程复活就像没法让烧完的蜡烛再点一次——你得拿一根新的。生活类比火箭发射。倒计时结束、火箭升空你不能对着同一个火箭再按一次发射按钮——要么它还在飞已经启动了要么已经烧完了TERMINATED。四、正确姿势需要新线程就创建新对象// ❌ 复用同一个 Thread 对象ThreadtnewThread(task);t.start();t.start();// 报错// ✅ 创建新的 Thread 对象newThread(task).start();newThread(task).start();// 两个新线程没问题 // ✅ 更好的方式用线程池ExecutorServicepoolExecutors.newFixedThreadPool(2);pool.submit(task);pool.submit(task);// 线程池自动复用线程 五、Thread 的状态机为什么只能 start 一次start() NEW ──────────────────→ RUNNABLE │ ┌──────────┼──────────┐ ↓ ↓ ↓ BLOCKED WAITING TIMED_WAITING │ │ │ └──────────┴──────────┘ │ ↓ TERMINATEDthreadStatus 值对应0 NEW还没 start其他值 已启动RUNNABLE/BLOCKED/WAITING/TERMINATED 等start() 检查的就是这个值非 0 直接拒绝。run() vs start() 全景run() vs start() 全景 start() ├── 作用启动新线程 ├── 底层native start0() → 创建 OS 线程 → JVM 回调 run() ├── 只能调用一次重复调用抛 IllegalThreadStateException └── 线程状态NEW → RUNNABLE run() ├── 作用在当前线程执行任务 ├── 底层普通方法调用无新线程 ├── 可以反复调用就是普通方法 └── 线程状态无变化 线程生命周期单向不可逆 NEW → RUNNABLE → TERMINATED ↕ BLOCKED / WAITING / TIMED_WAITING 口诀start 建线程调一次run 是内容可反复 线程生命周期单行道start 过了不回头。回答技巧与点评标准回答直接调用 run() 不会创建新线程只是在当前线程中执行 run() 方法体等同于普通方法调用。start() 才会调用 native start0() 创建操作系统线程由 JVM 在新线程中回调 run()。调用两次 start() 会抛 IllegalThreadStateException因为线程生命周期是单向的start() 内部会检查 threadStatus非 0即已启动过就抛异常。需要再次执行任务应该创建新的 Thread 对象或使用线程池。加分回答设计哲学线程状态的单向流转是操作系统的底层设计——OS 线程一旦终止其资源栈、寄存器等已被回收Java 不可能在 JVM 层面复活一个 OS 线程。IllegalThreadStateException 是 Java 对底层不可逆性的上层表达Runnable 的优势正是因为 Thread 不能重复 start才更应该用 Runnable——任务是可复用的Thread 对象是一次性的。把任务和执行载体分离既省资源又灵活线程池的设计动机线程池的核心价值就是线程复用——避免了反复创建销毁 OS 线程的开销。Worker 线程跑完一个任务不退出而是循环取下一个任务本质上是绕过了线程只能 start 一次的限制面试官点评这道题考的是你对线程生命周期和底层机制的理解。能说出run() 不创建新线程只是入门能讲清 start0() 的 native 调用、threadStatus 的状态检查、以及线程生命周期单向不可逆的设计原因才说明你真正理解了线程的本质。如果你还能引出线程池的复用设计面试官会认为你有全局视野。原文阅读内容有帮助点赞、收藏、关注三连评论区等你

相关文章:

孤舟笔记 并发篇十八 为什么启动线程不能直接调用run()方法?调用两次start()又会怎样?这个设计藏着大智慧

文章目录 一、先说结论:run() 和 start() 的核心区别二、直接调用 run():根本没有新线程start() 源码做了什么? 三、调两次 start():直接报错四、正确姿势:需要新线程就创建新对象五、Thread 的状态机:为什…...

别再只看ROC了!用‘价格斜率’构建ETF轮动策略,实测改善回撤(附Python代码)

价格斜率:重构ETF动量轮动的量化新视角 当大多数量化交易者还在用传统的收益率指标(ROC)衡量ETF动量时,市场已经悄悄奖励那些发现价格斜率价值的先行者。去年一位私募基金经理在内部测试中发现,将沪深300ETF的20日价格…...

保姆级教程:手把手教你修改PX4机型文件,让自定义无人机在QGC上完美显示

深度解析PX4机型文件定制:从脚本修改到QGC无缝集成实战指南 当你完成了一架自定义无人机的PX4固件开发,满心欢喜地打开QGroundControl(QGC)准备调试时,却发现机型列表中根本找不到自己的作品——这种挫败感我太熟悉了…...

TVA与CNN的历史性对决(3)

重磅预告:本专栏将独家连载新书《AI视觉技术:从入门到进阶》精华内容。本书是《AI视觉技术:从进阶到专家》的权威前导篇,特邀美国 TypeOne 公司首席科学家、斯坦福大学博士 Bohan 担任技术顾问。Bohan师从美国三院院士、“AI教母”…...

RH850 RS-CANFD中断配置保姆级教程:从Channel 2实战到寄存器位操作详解

RH850 RS-CANFD中断配置实战指南:从寄存器解析到Channel 2完整实现 当你在RH850评估板上第一次尝试配置RS-CANFD中断时,是否曾被那些神秘的寄存器位和中断向量表搞得晕头转向?作为从STM32转战瑞萨平台的工程师,我完全理解这种困惑…...

CNN与TVA的历史性对决(2)

重磅预告:本专栏将独家连载新书《AI视觉技术:从入门到进阶》精华内容。本书是《AI视觉技术:从进阶到专家》的权威前导篇,特邀美国 TypeOne 公司首席科学家、斯坦福大学博士 Bohan 担任技术顾问。Bohan师从美国三院院士、“AI教母”…...

Discord集成Ollama:本地大模型AI助手部署与实战指南

1. 项目概述与核心价值 最近在折腾AI应用集成,发现一个挺有意思的项目叫 kevinthedang/discord-ollama 。简单来说,它就是一个让你能在Discord聊天服务器里,直接调用本地部署的Ollama大语言模型的机器人。想象一下,你和朋友在Di…...

【Docker 27量子计算环境适配白皮书】:20年CNCF+量子实验室联合验证的7大不可绕过兼容陷阱

更多请点击: https://intelliparadigm.com 第一章:Docker 27量子计算环境适配的演进逻辑与战略定位 随着量子计算软件栈从原型验证迈向工程化部署,容器化运行时对量子模拟器、QPU驱动接口及混合量子-经典工作流的支持能力成为关键瓶颈。Dock…...

AI辅助全栈开发实战:基于Cursor构建MERN待办事项应用

1. 项目概述:一个由AI驱动的全栈待办事项应用最近在GitHub上看到一个挺有意思的项目,叫santosflores/todo_list_cursor。光看名字,你可能会觉得这又是一个平平无奇的待办事项列表应用,市面上类似的工具没有一千也有八百。但如果你…...

3步掌握NHSE:动物森友会存档编辑器的深度应用指南

3步掌握NHSE:动物森友会存档编辑器的深度应用指南 【免费下载链接】NHSE Animal Crossing: New Horizons save editor 项目地址: https://gitcode.com/gh_mirrors/nh/NHSE NHSE(New Horizons Save Editor)是一款专为《集合啦&#xff…...

DeepSeek LeetCode 2040.两个有序数组的第 K 小乘积 Python3实现

python from typing import List import bisectclass Solution:def kthSmallestProduct(self, nums1: List[int], nums2: List[int], k: int) -> int:# 统计乘积 < mid 的个数def count(mid: int) -> int:cnt 0for a in nums1:if a > 0:# a * b < mid > b…...

Substrate跨链桥实战:从架构设计到安全部署

1. 项目概述与核心价值最近在折腾一个跨链数据聚合的项目&#xff0c;中间件选型时&#xff0c;一个叫buremba/sub-bridge的开源项目进入了我的视野。这名字乍一看&#xff0c;sub很容易让人联想到 Substrate 区块链框架&#xff0c;而bridge则直指“桥”这个核心功能。没错&am…...

Ubuntu 20.04下搞定gici-open编译:从glog报错到ceres版本冲突的保姆级排坑指南

Ubuntu 20.04下gici-open编译全攻略&#xff1a;从依赖管理到实战调试 在GNSS/INS/Camera多传感器融合领域&#xff0c;gici-open作为上海交通大学最新开源的高精度定位框架&#xff0c;凭借其整合RTKLIB、OKVIS等知名算法的优势&#xff0c;正成为研究者和工程师关注的焦点。…...

如何用XXMI启动器轻松管理游戏模组:完整指南

如何用XXMI启动器轻松管理游戏模组&#xff1a;完整指南 【免费下载链接】XXMI-Launcher Modding platform for GI, HSR, WW and ZZZ 项目地址: https://gitcode.com/gh_mirrors/xx/XXMI-Launcher XXMI-Launcher是一款开源的游戏模组管理平台&#xff0c;专门为《原神》…...

SketchUp STL插件:5分钟实现3D设计到打印的无缝转换

SketchUp STL插件&#xff1a;5分钟实现3D设计到打印的无缝转换 【免费下载链接】sketchup-stl A SketchUp Ruby Extension that adds STL (STereoLithography) file format import and export. 项目地址: https://gitcode.com/gh_mirrors/sk/sketchup-stl 你是否在Sket…...

ArcGIS ModelBuilder实战:一键生成建筑矢量阴影,告别手动繁琐操作

ArcGIS ModelBuilder实战&#xff1a;一键生成建筑矢量阴影&#xff0c;告别手动繁琐操作 城市规划师小李最近接了个新项目——为某商业区绘制带阴影效果的建筑分布图。当他打开ArcGIS准备大展拳脚时&#xff0c;却发现手动创建建筑阴影的步骤繁琐得令人抓狂&#xff1a;每个建…...

SRS WebRTC部署踩坑实录:WHIP 404报错?可能是你的证书和端口配置错了

SRS WebRTC部署实战&#xff1a;WHIP 404报错深度排查指南 引言 当你满怀期待地按照官方文档部署SRS WebRTC服务&#xff0c;却在关键时刻遭遇WHIP接口404报错时&#xff0c;那种挫败感我深有体会。作为一名经历过多次类似问题的开发者&#xff0c;我理解这种看似简单却令人抓狂…...

QMCDecode macOS音频解密终极指南:3分钟学会QQ音乐加密格式破解

QMCDecode macOS音频解密终极指南&#xff1a;3分钟学会QQ音乐加密格式破解 【免费下载链接】QMCDecode QQ音乐QMC格式转换为普通格式(qmcflac转flac&#xff0c;qmc0,qmc3转mp3, mflac,mflac0等转flac)&#xff0c;仅支持macOS&#xff0c;可自动识别到QQ音乐下载目录&#xf…...

大语言模型长上下文处理能力评测框架LOCA-bench解析

1. 项目背景与核心价值最近在AI领域出现了一个很有意思的现象&#xff1a;大语言模型&#xff08;LLM&#xff09;的上下文窗口正在以惊人的速度扩张。从最初的几千token到现在的百万级上下文处理能力&#xff0c;这种进化带来了新的机遇和挑战。LOCA-bench正是在这样的背景下诞…...

Kai 9000:构建具备持久记忆与跨平台执行能力的开源AI助手

1. 项目概述&#xff1a;一个全平台、开源的智能体新范式 如果你和我一样&#xff0c;对市面上那些“健忘”的AI助手感到厌倦&#xff0c;每次对话都像在和一个失忆症患者重新认识&#xff0c;那么你可能会对Kai 9000产生兴趣。这不是又一个套壳的ChatGPT前端&#xff0c;而是一…...

GetQzonehistory终极指南:一键备份QQ空间十年回忆的完整方案

GetQzonehistory终极指南&#xff1a;一键备份QQ空间十年回忆的完整方案 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否曾担心那些记录青春岁月的QQ空间说说不小心丢失&#xff…...

从2010到2024:手把手教你用Python分析CUMCM历年赛题趋势(附数据与代码)

从2010到2024&#xff1a;用Python解码数学建模竞赛的15年演变密码 数学建模竞赛的题目就像一面镜子&#xff0c;映照出时代的技术热点和社会需求。当我第一次整理这15年的赛题时&#xff0c;发现2010年的"储油罐变位识别"和2024年的"交通流量管控"之间&am…...

Pseudogen:基于机器翻译技术的智能伪代码生成系统架构设计

Pseudogen&#xff1a;基于机器翻译技术的智能伪代码生成系统架构设计 【免费下载链接】pseudogen A tool to automatically generate pseudo-code from source code. 项目地址: https://gitcode.com/gh_mirrors/ps/pseudogen 在当今软件开发与教育领域&#xff0c;源代…...

Keil工程里.c文件显示灰色带钥匙?从‘文件导入’到‘工程管理’的深度避坑指南

Keil工程文件图标异常全解析&#xff1a;从灰色钥匙到编译失败的终极解决方案 当你第一次在Keil工程中看到某个.c文件显示灰色并带钥匙图标时&#xff0c;那种困惑感我至今记忆犹新。三年前接手一个遗留项目时&#xff0c;我花了整整两天时间才弄明白为什么修改的代码始终不生…...

Arm DesignStart项目IP资源解析与应用指南

1. Arm Flexible Access DesignStart项目概述 在芯片设计领域&#xff0c;IP授权是构建复杂SoC的核心环节。Arm Flexible Access项目通过标准化流程显著降低了技术门槛&#xff0c;而其中的DesignStart计划更是为初创企业和学术机构提供了快速启动芯片设计的入口。这个计划包含…...

语言模型微调与BoN优化方法详解

1. 语言模型微调与BoN优化方法概述 语言模型微调是自然语言处理领域的一项核心技术&#xff0c;它通过在预训练模型的基础上&#xff0c;针对特定任务或领域数据进行二次训练&#xff0c;使模型能够更好地适应目标场景。这种技术广泛应用于代码生成、文本摘要、对话系统等多个领…...

大模型KV缓存卸载技术:原理、挑战与优化方案

1. KV缓存卸载技术背景与核心挑战在Transformer架构的大语言模型(LLM)推理过程中&#xff0c;KV&#xff08;Key-Value&#xff09;缓存机制通过存储注意力计算中的键值对来避免重复计算&#xff0c;显著提升了自回归生成的效率。然而随着模型支持上下文长度的不断增加&#xf…...

告别原生驱动依赖:用 TDengine 的 taosAdapter 为你的 Python/Node.js 项目轻松接入时序数据

轻量级时序数据集成实战&#xff1a;TDengine REST API 在 Python/Node.js 项目中的高效应用 时序数据处理正成为物联网、金融科技和工业互联网领域的核心需求。传统方案往往需要安装臃肿的原生驱动&#xff0c;给开发部署带来额外负担。TDengine 的 taosAdapter 组件通过 RES…...

如何用Zotero茉莉花插件快速搞定中文文献管理:3大核心功能详解

如何用Zotero茉莉花插件快速搞定中文文献管理&#xff1a;3大核心功能详解 【免费下载链接】jasminum A Zotero add-on to retrive CNKI meta data. 一个简单的Zotero 插件&#xff0c;用于识别中文元数据 项目地址: https://gitcode.com/gh_mirrors/ja/jasminum 还在为…...

Rdkit批量处理技巧:如何用PandasTools高效可视化你的化合物库(DataFrame操作指南)

Rdkit与Pandas高效协作&#xff1a;化合物库可视化全流程实战指南 药物研发过程中&#xff0c;化学家们经常需要处理包含数千甚至数万种化合物的数据库。如何快速浏览这些分子的结构特征&#xff1f;传统方法需要逐个打开分子查看器&#xff0c;效率低下且容易遗漏关键信息。本…...