《Java 100 天进阶之路》第60.1篇:多线程易混淆概念对比集(2026版)

《Java 100 天进阶之路》第60.1篇:多线程易混淆概念对比集(2026版)
第60.1篇多线程易混淆概念对比集2026版系列导航《Java 100 天进阶之路》完整目录 |⬅️ 上一篇第60篇并发编程面试压轴题 |➡️ 下一篇第60.2篇面试官追问陷阱合集待发布️ 本文阅读地图2 分钟速览多线程专题最容易混淆的概念一次性整理完毕面试官最爱问“A和B有什么区别”本文汇总 15 组高频易混淆概念每组配一句话总结 详细对比对比组一句话区分sleep vs waitsleep 不释放锁wait 释放锁start vs runstart 启动新线程run 是普通方法调用synchronized vs ReentrantLockJVM内置自动释放 vs API手动精细控制volatile vs synchronized轻量级可见性 vs 重量级原子性JMM vs JVM内存结构管“怎么看见” vs 管“存哪里”死锁 vs 活锁 vs 饥饿永久阻塞 vs 空转 vs 缓慢thenApply vs thenCompose同步转换 vs 串联异步任务allOf vs anyOf等全部 vs 等任意exceptionally vs handle vs whenComplete异常兜底 vs 全部处理 vs 收尾get vs join受检异常 vs 非受检异常AtomicInteger vs LongAdder强一致性 vs 高吞吐弱一致AtomicStampedReference vs AtomicMarkableReference版本号 vs 布尔标记InheritableThreadLocal vs TransmittableThreadLocal父子线程 vs 线程池remove vs set(null)删 Entry vs 改值为 nullshutdown vs shutdownNow优雅关闭 vs 立即中断文章目录第60.1篇多线程易混淆概念对比集2026版️ 本文阅读地图2 分钟速览一、sleep() vs wait()二、start() vs run()三、synchronized vs ReentrantLock四、volatile vs synchronized五、JMM vs JVM 内存结构六、死锁 vs 活锁 vs 饥饿七、thenApply vs thenCompose八、allOf vs anyOf九、exceptionally vs handle vs whenComplete十、get() vs join()十一、AtomicInteger vs LongAdder十二、AtomicStampedReference vs AtomicMarkableReference十三、InheritableThreadLocal vs TransmittableThreadLocal十四、remove() vs set(null)十五、shutdown() vs shutdownNow() 你的学习进度 下一篇文章预告一、sleep() vs wait()对比维度sleep()wait()所属类Thread 静态方法Object 实例方法是否释放锁❌ 不释放✅ 释放锁唤醒方式时间到自动醒来需要notify()/notifyAll()唤醒使用位置任何地方必须在 synchronized 块中抛异常InterruptedExceptionInterruptedException 一句话总结sleep 抱着锁睡觉wait 放开锁等人叫。二、start() vs run()对比维度start()run()是否创建新线程✅ 是启动新线程❌ 否在当前线程执行JVM 调用JVM 自动调用run()程序直接调用可多次调用❌ 只能调用一次✅ 可多次调用普通方法 一句话总结start 是“请 JVM 开新线程干活”run 是“自己干这个活”。三、synchronized vs ReentrantLock对比维度synchronizedReentrantLock实现层级JVM 内置关键字JDK API 类锁释放自动释放异常也释放需在 finally 中手动 unlock锁升级✅ 有偏向→轻量→重量❌ 无公平锁❌ 非公平支持公平/非公平中断响应❌ 不可中断✅lockInterruptibly()超时获取❌ 不支持✅tryLock(timeout)条件变量wait()/notify()Condition多个虚拟线程❌ 导致 Pinning✅ 推荐使用 一句话总结synchronized 是 JVM 自动挡ReentrantLock 是 JDK 手动挡。四、volatile vs synchronized对比维度volatilesynchronized原子性❌ 不保证✅ 保证可见性✅ 保证✅ 保证有序性✅ 禁止重排✅ 保证锁机制无锁内存语义约束排他锁OS 级互斥性能开销低比普通变量慢约 20%高用户态/内核态切换适用场景状态标记、DCL复合操作、需要原子性 一句话总结volatile 是“轻量级交警”只管可见性synchronized 是“重型保安”管一切并发问题。五、JMM vs JVM 内存结构对比维度JMMJava 内存模型JVM 内存结构是什么规范——内存访问规则物理结构——数据存储位置解决什么问题线程间数据何时可见、执行顺序如何保证数据存在哪里、怎么存核心内容主内存 工作内存堆、栈、元空间、程序计数器设计目标屏蔽硬件和系统差异定义 JVM 运行时数据区域 一句话总结JMM 管“怎么看见”JVM 内存结构管“存哪里”。六、死锁 vs 活锁 vs 饥饿对比维度死锁活锁饥饿状态永久阻塞不阻塞不断重试失败有进展但缓慢是否推进❌ 完全不推进❌ 无法推进空转✅ 推进极慢原因循环等待资源过度谦让或冲突重试低优先级被抢占解决方案统一锁顺序、tryLock引入随机退避提高优先级、公平锁 一句话总结死锁是“互相等死”活锁是“互相让路让到死”饥饿是“被插队到死”。七、thenApply vs thenCompose对比维度thenApplythenCompose参数FunctionT, U同步转换FunctionT, CompletionStageU异步串联返回值CompletableFutureU直接转换CompletableFutureU扁平化是否创建新 Future❌✅ 返回新 Future适用场景同步转换结果串联依赖的异步任务 一句话总结thenApply 同步换一下thenCompose 串联异步任务。八、allOf vs anyOf对比维度allOfanyOf等待条件所有任务完成任意一个任务完成返回值CompletableFutureVoidCompletableFutureObject结果获取需从原始 Future 中取直接返回第一个完成的结果适用场景并行聚合多个结果竞速择优多数据源选最快 一句话总结allOf 等全部anyOf 等最快。九、exceptionally vs handle vs whenComplete对比维度exceptionallyhandlewhenComplete触发时机仅异常时成功或异常成功或异常返回值兜底值可继续链式处理不改变结果异常传播消费异常返回正常不自动消费异常继续传播适用场景提供备用结果统一处理成功/失败日志、清理等收尾 一句话总结exceptionally 是 catch给兜底handle 是 finally都处理whenComplete 是监工只看不干。十、get() vs join()对比维度get()join()异常类型受检异常ExecutionException非受检异常CompletionException代码简洁度需 try-catch无需 try-catch获取原始异常e.getCause()需拆cause超时支持✅get(timeout, unit)❌ 不支持适用场景传统方式生产推荐 一句话总结join 更简洁生产推荐get 更传统支持超时。十一、AtomicInteger vs LongAdder对比维度AtomicIntegerLongAdder底层原理单一 value CASbase Cell[] 分段累加高并发性能一般大量 CAS 失败自旋优秀分散竞争4 倍内存占用小较大Cell[] 数组数据一致性强一致性弱一致性sum()是近似值适用场景通用计数、需要精确值写多读少、高并发统计 一句话总结AtomicInteger 是“一个收银台”LongAdder 是“多个收银台分流”。十二、AtomicStampedReference vs AtomicMarkableReference对比维度AtomicStampedReferenceAtomicMarkableReference标记类型int版本号可自增boolean真/假区分变更次数✅ 可无限区分❌ 最多区分 1 次适用场景无锁栈/队列需追踪变更次数仅需知道“是否被修改过”内存开销较大stamp 占 int 空间较小boolean 标记 一句话总结stamp 是“版本号”能计数mark 是“标签”只看有没有改。十三、InheritableThreadLocal vs TransmittableThreadLocal对比维度InheritableThreadLocalTransmittableThreadLocal适用范围父子线程新建子线程时传递线程池线程复用场景提供方JDK 自带阿里开源transmittable-thread-local实现原理Thread.init()时复制父线程值包装 Runnable捕获/注入/清理适用场景简单父子线程微服务链路追踪、线程池上下文传递 一句话总结Inheritable 只管“亲儿子”TTL 管“外包工”线程池。十四、remove() vs set(null)对比维度remove()set(null)操作效果删除整个 Entrykey value仅将 value 设为 nullEntry 是否残留❌ 彻底清除✅ Entry 仍存在key 仍有效内存是否释放✅ 完全释放❌ Entry 仍占用内存推荐做法✅ 推荐❌ 不推荐 一句话总结remove 是“连根拔起”set(null) 是“把内容清空但盒子还在”。十五、shutdown() vs shutdownNow()对比维度shutdown()shutdownNow()是否接受新任务❌ 不接受❌ 不接受是否等待现有任务完成✅ 等待❌ 不等待尝试中断未执行任务继续执行返回未执行任务列表是否保证任务完整执行✅ 保证❌ 可能中断适用场景优雅关闭紧急关闭 一句话总结shutdown 是“干完手头活再下班”shutdownNow 是“立即关门活扔出来”。 你的学习进度当前第60.1篇 ·多线程专题外挂易混淆概念对比集✅ 已完成基础篇44篇 第45~60篇 第60.1篇 正在学第60.1篇⏳ 待学习第60.2篇追问陷阱合集 第61~108篇 完整目录 学习指南 | 订阅本专栏不错过每一篇 下一篇文章预告下一篇《第60.2篇面试官追问陷阱合集》内容简介11 道多线程面试高频追问陷阱直接背诵拉高面试区分度《Java 100 天进阶之路 | 从入门到上岗就业》每天一篇建议收藏 关注一起100天拿offer 点击关注我更新后第一时间收到推送