<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>《Java 并发编程·线程与内存模型》 · 全书目录与章节索引（50 篇） on PlumePHP</title><link>https://plumephp.com/posts/books/java%E5%B9%B6%E5%8F%91%E5%9F%BA%E7%A1%80/</link><description>Recent content in 《Java 并发编程·线程与内存模型》 · 全书目录与章节索引（50 篇） on PlumePHP</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Wed, 28 Oct 2026 20:49:00 +0800</lastBuildDate><atom:link href="https://plumephp.com/posts/books/java%E5%B9%B6%E5%8F%91%E5%9F%BA%E7%A1%80/index.xml" rel="self" type="application/rss+xml"/><item><title>《Java 并发编程·线程与内存模型》附录 B 并发诊断命令与 JFR 事件</title><link>https://plumephp.com/java-conc-basic-appendix-b-diagnostics/</link><pubDate>Wed, 28 Oct 2026 20:49:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-appendix-b-diagnostics/</guid><description>把并发问题排查要用的 jcmd 子命令、线程转储读法、JFR 事件与过滤命令整理成一张表，并附本机 Temurin 25.0.5 上真实抓取的 Thread.print、jdk.JavaMonitorEnter、jdk.ThreadPark、jdk.VirtualThreadPinned 输出片段与解读。</description></item><item><title>《Java 并发编程·线程与内存模型》附录 A 并发 API 速查</title><link>https://plumephp.com/java-conc-basic-appendix-a-api/</link><pubDate>Wed, 28 Oct 2026 20:48:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-appendix-a-api/</guid><description>把 JDK 25 常用并发 API 按线程与执行、同步器、并发容器、原子类、虚拟线程与结构化并发五组整理成速查表，每条给出核心方法、语义要点与选择边界，并附方法命名规律和「我要做什么 → 用哪个」反查表，以及各 API 的「什么时候不要用」。</description></item><item><title>《Java 并发编程·线程与内存模型》15.3 从 ExecutorService 迁移的边界</title><link>https://plumephp.com/java-conc-basic-15-3-migration-limits/</link><pubDate>Wed, 28 Oct 2026 20:47:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-15-3-migration-limits/</guid><description>把同一段三下游扇出分别用虚拟线程池和 StructuredTaskScope 实现：代码行数几乎相同、token 反而多 8 个，失败到返回却从 828ms 降到 140ms。本节给出迁移的四条硬边界——不可跨作用域、异常要解包、虚拟线程不是重点、preview 风险，并附真实报错。</description></item><item><title>《Java 并发编程·线程与内存模型》15.2 Joiner、失败传播与取消</title><link>https://plumephp.com/java-conc-basic-15-2-joiner-failure/</link><pubDate>Wed, 28 Oct 2026 20:46:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-15-2-joiner-failure/</guid><description>awaitAll 只等结果不管失败，真正让「一个下游挂了、其余立刻停」的是 Joiner。本节用三个下游扇出实测五个内置 Joiner 的返回类型与取消时机：失败后 2ms 兄弟任务被中断，join 抛 FailedException 并保留原始 cause。</description></item><item><title>《Java 并发编程·线程与内存模型》15.1 StructuredTaskScope 的作用域</title><link>https://plumephp.com/java-conc-basic-15-1-structured-scope/</link><pubDate>Wed, 28 Oct 2026 20:45:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-15-1-structured-scope/</guid><description>StructuredTaskScope 把一次请求 fork 出的子任务收进词法作用域：关闭前必须 join，关闭后不留活线程。本节用两路查询聚合实测 open/fork/join/close 的契约、子任务三种状态与超时取消，并对照 ExecutorService 说明任务生命周期为什么要绑在代码块上。</description></item><item><title>《Java 并发编程·线程与内存模型》14.3 虚拟线程下的池、ThreadLocal 与限流</title><link>https://plumephp.com/java-conc-basic-14-3-pool-threadlocal-adapt/</link><pubDate>Wed, 28 Oct 2026 20:44:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-14-3-pool-threadlocal-adapt/</guid><description>虚拟线程把每条阻塞任务降到约 1 KB，但连接池、下游 QPS 和 ThreadLocal 副本数没变。本节实测 1 000 个任务不设限时 maxInFlight=1 000、36–57 ms 打穿下游；加 Semaphore(16) 后恒定 16、耗时 2 256–2 286 ms。另测 10 万条虚拟线程各存 1 KB ThreadLocal 多占约 104 MB。</description></item><item><title>《Java 并发编程·线程与内存模型》14.2 pinning：JDK 25 还剩什么</title><link>https://plumephp.com/java-conc-basic-14-2-pinning/</link><pubDate>Wed, 28 Oct 2026 20:43:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-14-2-pinning/</guid><description>JDK 24 的 JEP 491 让 synchronized 不再 pin 虚拟线程，‘虚拟线程里别用 synchronized’已经过期。本节用 JFR 逐项验证：20 条同步块阻塞 0 个 pin 事件，类初始化阻塞 19 个；FFM usleep 虽不触发事件，却让 10 条载体全被占住，探针延迟 437–450 ms。</description></item><item><title>《Java 并发编程·线程与内存模型》14.1 虚拟线程的调度模型</title><link>https://plumephp.com/java-conc-basic-14-1-scheduler-carrier/</link><pubDate>Wed, 28 Oct 2026 20:42:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-14-1-scheduler-carrier/</guid><description>平台线程一条要占 0.5–1 MB 栈，一万并发就逼近内存红线。本节从 1:1 与 M:N 的差别讲起，拆开载体线程、mount/unmount 和栈片段，并在本机用 -Xmx512m 创建 10 万个虚拟线程：堆占用约 89–103 MB、启动 91–132 ms，载体线程只有 10 条。</description></item><item><title>《Java 并发编程·线程与内存模型》13.3 上下文传递与线程池隔离</title><link>https://plumephp.com/java-conc-basic-13-3-context-propagation/</link><pubDate>Wed, 28 Oct 2026 20:41:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-13-3-context-propagation/</guid><description>异步把执行线程换掉了，ThreadLocal 里的请求 ID 也就断了。本节实测 commonPool 与裸线程池里读到的上下文都是 null，给出在提交时捕获、执行时安装的 Executor 装饰器，并用 1 线程池的 418ms 对 20ms 说明为什么三个下游要各自隔离线程池。</description></item><item><title>《Java 并发编程·线程与内存模型》13.2 异常、超时与取消</title><link>https://plumephp.com/java-conc-basic-13-2-exception-timeout/</link><pubDate>Wed, 28 Oct 2026 20:40:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-13-2-exception-timeout/</guid><description>exceptionally、handle、whenComplete 的差别在于「谁能改变结果」，而不是「谁会被调用」。本节实测 orTimeout 在 200ms 预算下于 203–208ms 触发，底层任务照常跑完且未被中断；cancel(true) 同样不中断。三路通知的降级链整体 217ms，而不是串行至少 860ms。</description></item><item><title>《Java 并发编程·线程与内存模型》13.1 CompletableFuture 的创建与组合</title><link>https://plumephp.com/java-conc-basic-13-1-compose/</link><pubDate>Wed, 28 Oct 2026 20:39:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-13-1-compose/</guid><description>Future 只能阻塞取值，CompletableFuture 把「结果还没到」变成一个可以继续挂步骤的对象。本节实测默认执行器是 parallelism=9 的 commonPool，thenApply 在完成者线程上执行，三路下游扇出从串行 290ms 降到 120ms，并给出 allOf 不 fail-fast 的真实证据。</description></item><item><title>《Java 并发编程·线程与内存模型》12.3 分治拆分、阈值与异常</title><link>https://plumephp.com/java-conc-basic-12-3-divide-conquer/</link><pubDate>Wed, 28 Oct 2026 20:38:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-12-3-divide-conquer/</guid><description>阈值同时决定任务数和叶子成本：切太小，任务对象与调度开销吃掉收益；切太大，叶子里的插入排序退化成平方复杂度。本机 100 万元素归并排序实测，阈值 1 是 140ms、16 是 21ms、65536 是 1629ms，顺序版 105ms。文末用实测输出说明异常如何跨线程包装，以及 cancel 为什么停不下正在跑的叶子。</description></item><item><title>《Java 并发编程·线程与内存模型》12.2 并行流的边界与 commonPool 陷阱</title><link>https://plumephp.com/java-conc-basic-12-2-parallel-stream/</link><pubDate>Wed, 28 Oct 2026 20:37:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-12-2-parallel-stream/</guid><description>parallel() 只多了一个方法调用，却把用哪个池、拆多细、有没有副作用三件事都藏了起来。本机实测：同样 20 个 10ms 任务，commonPool 空闲时 31ms，被阻塞任务占满后 276ms；1000 个元素的并行流比顺序流慢 2.49 倍；36 个阻塞任务在 commonPool 上 1231ms，换成 16 线程的自定义池 916ms。</description></item><item><title>《Java 并发编程·线程与内存模型》12.1 工作窃取与 ForkJoinPool</title><link>https://plumephp.com/java-conc-basic-12-1-work-stealing/</link><pubDate>Wed, 28 Oct 2026 20:36:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-12-1-work-stealing/</guid><description>线程池是任务等线程，ForkJoinPool 是任务找线程：每个 worker 一个双向队列，自己从头部取最新的任务，空闲线程从尾部偷最老的任务。本机 10 核实测 commonPool 并行度 9，1 亿整数求和在四轮里从顺序 67ms 降到 13ms，池自己记录到 189 次窃取；并行度改成 3 后是 17ms。</description></item><item><title>《Java 并发编程·线程与内存模型》11.3 调度漂移、幂等与补偿</title><link>https://plumephp.com/java-conc-basic-11-3-schedule-drift/</link><pubDate>Wed, 28 Oct 2026 20:35:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-11-3-schedule-drift/</guid><description>固定频率和固定延迟的分母不同：前者对齐计划时刻，后者从执行结束开始算。本机实测同一个 200ms 周期、80ms 耗时的任务，fixedRate 六次的落后量稳定在 1–9ms，fixedDelay 则从 82ms 一路涨到 444ms；单次执行超过周期时，fixedRate 不丢弃欠账而是背靠背补跑。文末给出幂等键与补偿的落地写法。</description></item><item><title>《Java 并发编程·线程与内存模型》11.2 延迟队列与时间轮</title><link>https://plumephp.com/java-conc-basic-11-2-delayqueue-timewheel/</link><pubDate>Wed, 28 Oct 2026 20:34:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-11-2-delayqueue-timewheel/</guid><description>延迟任务有两种组织方式：堆，或者时间轮。本文拆开 DelayQueue 的优先级队列与 leader 线程，实测乱序入队仍按剩余延迟出队、指数退避重试在 +0/+60/+173ms 完成；再手写一个 8 槽 50ms 的时间轮，对比同组任务的量化误差：时间轮平均 30ms，DelayQueue 平均 2.2ms。</description></item><item><title>《Java 并发编程·线程与内存模型》11.1 Timer 的缺陷与 ScheduledThreadPoolExecutor</title><link>https://plumephp.com/java-conc-basic-11-1-timer-vs-stpe/</link><pubDate>Wed, 28 Oct 2026 20:33:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-11-1-timer-vs-stpe/</guid><description>Timer 只有一条线程、一个异常就能让它彻底停摆，还把相对延迟换算成墙上时钟的绝对时刻。三个实验对照：慢任务把后续任务从 50ms 推到 317ms；抛异常后 Timer 线程死亡、700ms 内只跑了 1 次，而 STPE 里健康任务照跑 8 次；字节码显示两者分别取 currentTimeMillis 与 nanoTime。</description></item><item><title>《Java 并发编程·线程与内存模型》10.3 监控、动态调参与关闭</title><link>https://plumephp.com/java-conc-basic-10-3-monitor-shutdown/</link><pubDate>Wed, 28 Oct 2026 20:32:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-10-3-monitor-shutdown/</guid><description>线程池上线之后要回答三个运维问题：指标怎么读、参数能不能改、进程怎么退。本节逐个核对 getActiveCount、队列长度、getCompletedTaskCount 的口径与误差，实测 setCorePoolSize 上调立即补线程、下调却要等 keepAlive 才收敛，并对比 shutdown 与 shutdownNow 的返回值和中断行为。</description></item><item><title>《Java 并发编程·线程与内存模型》10.2 队列与拒绝策略</title><link>https://plumephp.com/java-conc-basic-10-2-queue-rejection/</link><pubDate>Wed, 28 Oct 2026 20:31:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-10-2-queue-rejection/</guid><description>队列满、线程到顶之后发生什么，取决于拒绝策略。本节实测四种 JDK 拒绝策略在同一场景下的不同结果，解释 CallerRunsPolicy 如何在调用线程上形成反压、它在什么条件下会失效，并用无界队列实验证明 max 参数如何被架空，最后给出有界队列容量的推导方法与可记录指标的自定义拒绝策略。</description></item><item><title>《Java 并发编程·线程与内存模型》10.1 线程池七参数与执行流程</title><link>https://plumephp.com/java-conc-basic-10-1-executor-flow/</link><pubDate>Wed, 28 Oct 2026 20:30:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-10-1-executor-flow/</guid><description>把 ThreadPoolExecutor 的七个参数逐个拆开，说明 core、max、queue、keepAlive、工厂与拒绝策略各管哪一段，用三段判断还原 execute 的执行顺序，并以逐步提交实验打印 poolSize 与 queue 的真实变化，验证核心线程默认不超时、只有开启 allowCoreThreadTimeOut 才会归零。</description></item><item><title>《Java 并发编程·线程与内存模型》9.3 读写锁与 StampedLock</title><link>https://plumephp.com/java-conc-basic-09-3-readwrite-stampedlock/</link><pubDate>Wed, 28 Oct 2026 20:29:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-09-3-readwrite-stampedlock/</guid><description>读多写少的缓存该用什么锁：ReentrantReadWriteLock 让读并行、写互斥，StampedLock 再用版本戳把读变成乐观尝试。三版缓存代码对照，附读写并行、乐观读失效重试、不可重入、writeLock 不响应中断的本机实测输出。</description></item><item><title>《Java 并发编程·线程与内存模型》9.2 ReentrantLock 与 synchronized 的取舍</title><link>https://plumephp.com/java-conc-basic-09-2-reentrantlock-tradeoff/</link><pubDate>Wed, 28 Oct 2026 20:28:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-09-2-reentrantlock-tradeoff/</guid><description>ReentrantLock 比 synchronized 多出的四件事——可中断、超时、公平、多条件队列，逐项给出本机实测；再用 JFR 验证 JDK 25 默认配置下 synchronized 已不 pin 虚拟线程（LockingMode=1 可复现 20 次 pin），据此重新回答什么时候仍该坚持 synchronized。</description></item><item><title>《Java 并发编程·线程与内存模型》9.1 自旋、阻塞与 park/unpark</title><link>https://plumephp.com/java-conc-basic-09-1-spin-block/</link><pubDate>Wed, 28 Oct 2026 20:27:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-09-1-spin-block/</guid><description>从自旋锁的 CPU 代价讲到 LockSupport.park/unpark 的许可语义：许可最多一个、先 unpark 后 park 也生效、中断不清标志、虚假唤醒为何必须循环检查。附本机线程 dump 与 park 边界情形的真实输出，并给出借阅服务的唤醒式 worker。</description></item><item><title>《Java 并发编程·线程与内存模型》8.3 LongAdder 与高竞争累加</title><link>https://plumephp.com/java-conc-basic-08-3-longadder/</link><pubDate>Wed, 28 Oct 2026 20:26:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-08-3-longadder/</guid><description>从 Striped64 的 base + Cell[] 结构讲清 LongAdder 为什么能绕开单变量 CAS 的天花板：给出 JDK 25 的 add/sum 源码、cell 分片的实测形状、@Contended 与伪共享的真实编译约束，并在负载 155 的机器上如实记录 JMH 误差超过 50% 的数据不可引用。</description></item><item><title>《Java 并发编程·线程与内存模型》8.2 原子类家族与字段更新器</title><link>https://plumephp.com/java-conc-basic-08-2-atomic-family/</link><pubDate>Wed, 28 Oct 2026 20:25:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-08-2-atomic-family/</guid><description>把 java.util.concurrent.atomic 拆成基本、引用、数组、字段更新器四族：给出 JDK 25 的 getAndUpdate 源码与返回值语义、字段更新器省掉一个对象的代价与四条硬约束、实测的四种构造失败消息，并厘清 weakCompareAndSet 在 JDK 25 已被弃用为 plain 语义这件事。</description></item><item><title>《Java 并发编程·线程与内存模型》8.1 CAS 原理与 ABA</title><link>https://plumephp.com/java-conc-basic-08-1-cas-aba/</link><pubDate>Wed, 28 Oct 2026 20:24:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-08-1-cas-aba/</guid><description>从 compareAndSet 的 volatile 读写语义讲到失败重试的真实开销：用门闩固定交错，在无锁栈上把 ABA 复现成 2000/2000 次可重复的损坏，再用 AtomicStampedReference 压到 0/2000，并给出 AtomicMarkableReference 的 attemptMark 陷阱与本机实测输出。</description></item><item><title>《Java 并发编程·线程与内存模型》7.3 ScopedValue：JDK 25 的作用域值</title><link>https://plumephp.com/java-conc-basic-07-3-scopedvalue/</link><pubDate>Wed, 28 Oct 2026 20:23:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-07-3-scopedvalue/</guid><description>ScopedValue 用词法作用域取代线程绑定：绑定不可变、出了 run/call 自动解绑、结构化子任务自动继承、普通线程不继承。本机实测 JDK 25 上它已转正无需 preview，而 StructuredTaskScope 仍需 --enable-preview，附完整编译与运行输出。</description></item><item><title>《Java 并发编程·线程与内存模型》7.2 InheritableThreadLocal 与线程池断裂</title><link>https://plumephp.com/java-conc-basic-07-2-inheritable-pool/</link><pubDate>Wed, 28 Oct 2026 20:22:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-07-2-inheritable-pool/</guid><description>InheritableThreadLocal 只在线程创建时复制一次快照，这个前提在线程池里不成立。实测同一个池线程连续服务三个请求，读到的都是第一个请求的会员号；父线程在创建后改值，子线程仍看到旧值。拆解串值、丢失、残留、半更新四种失败形态，给出方法参数、提交侧捕获、Executor 装饰器三种显式透传写法。</description></item><item><title>《Java 并发编程·线程与内存模型》7.1 ThreadLocal 的实现与内存泄漏</title><link>https://plumephp.com/java-conc-basic-07-1-threadlocal-leak/</link><pubDate>Wed, 28 Oct 2026 20:21:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-07-1-threadlocal-leak/</guid><description>ThreadLocal 的哈希表、弱引用 key 与强引用 value 如何组合成一条泄漏路径。用反射读出 ThreadLocalMap 的 table 与 Entry 实测：6 个已失效的 ThreadLocal 仍留下 24 MiB 值，8 线程池不 remove 保留 32 MiB，remove 后为 0。</description></item><item><title>《Java 并发编程·线程与内存模型》6.3 shutdown hook 与释放顺序</title><link>https://plumephp.com/java-conc-basic-06-3-shutdown-hook/</link><pubDate>Wed, 28 Oct 2026 20:20:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-06-3-shutdown-hook/</guid><description>shutdown hook 是 JVM 退出前的最后一程，不是优雅停机的全部。本文用 50 次运行证明多个 hook 的启动顺序完全随机，实测异常不改变退出码、JVM 对 hook 没有超时、hook 里调用 System.exit 会卡死，并对比 SIGTERM、SIGKILL 与 Runtime.halt 的路径，最后给出 libraryd-conc 的单 hook 有序释放写法。</description></item><item><title>《Java 并发编程·线程与内存模型》6.2 两阶段终止与协作式取消</title><link>https://plumephp.com/java-conc-basic-06-2-two-phase-termination/</link><pubDate>Wed, 28 Oct 2026 20:19:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-06-2-two-phase-termination/</guid><description>两阶段终止只有一个骨架：volatile 停止标志、interrupt 唤醒阻塞、join 限时等待。本文给出可直接使用的 Worker 完整类，在本机对比只发信号、立即中断、超时升级三条关停路径，并用真实输出说明 Future.cancel(true) 只是请求：任务不检查中断时，cancel 返回 true 也停不下来。</description></item><item><title>《Java 并发编程·线程与内存模型》6.1 interrupt 的真实语义</title><link>https://plumephp.com/java-conc-basic-06-1-interrupt-semantics/</link><pubDate>Wed, 28 Oct 2026 20:18:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-06-1-interrupt-semantics/</guid><description>interrupt 不是杀死线程，只是把一个标志位置为 true，真正的退出仍要靠被中断线程自己检查。本文用 sleep、wait、join、synchronized 竞争与 ReentrantLock 在本机实测中断行为，说明 InterruptedException 为什么会清除标志、哪些阻塞根本不响应中断，并给出捕获后恢复标志再包装成 LoanException 的写法与边界。</description></item><item><title>《Java 并发编程·线程与内存模型》5.3 手写有界缓冲区</title><link>https://plumephp.com/java-conc-basic-05-3-bounded-buffer/</link><pubDate>Wed, 28 Oct 2026 20:17:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-05-3-bounded-buffer/</guid><description>从单锁 notifyAll 版写到 ReentrantLock 双条件版，补上关闭语义与中断处理，再和 ArrayBlockingQueue 正面对比。三个实现各跑 10 万元素全部有序正确，单锁版连续四次都在 39ms 以上，双条件版与 JDK 队列则贴着 20ms 上下波动。</description></item><item><title>《Java 并发编程·线程与内存模型》5.2 虚假唤醒与条件谓词循环</title><link>https://plumephp.com/java-conc-basic-05-2-spurious-wakeup/</link><pubDate>Wed, 28 Oct 2026 20:16:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-05-2-spurious-wakeup/</guid><description>wait 可能无缘无故返回，也可能醒来发现条件已被别人抢走，还可能信号早于等待而永久丢失。用两组实测对照说明：同一个双消费者场景里 if 版 100 轮全部取到 null，while 版 0 轮出错；而信号先发时裸 wait 等了 205ms 才超时。</description></item><item><title>《Java 并发编程·线程与内存模型》5.1 wait/notify 的正确姿势</title><link>https://plumephp.com/java-conc-basic-05-1-wait-notify/</link><pubDate>Wed, 28 Oct 2026 20:15:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-05-1-wait-notify/</guid><description>wait 会释放监视器，notify 不会——两组实测时间线把这件事讲清楚，也说明不在同步块内调用为什么会抛 IllegalMonitorStateException。再给一个能跑的生产者消费者最小实现，讲清条件判断为什么必须写成 while、notify 与 notifyAll 该怎么选、被唤醒之后还要重新抢锁。</description></item><item><title>《Java 并发编程·线程与内存模型》4.3 锁消除、锁粗化与偏向锁的移除</title><link>https://plumephp.com/java-conc-basic-04-3-lock-elision-inflation/</link><pubDate>Wed, 28 Oct 2026 20:14:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-04-3-lock-elision-inflation/</guid><description>JIT 对 synchronized 做了哪些手脚：逃逸分析如何让方法内的锁消失、锁粗化如何合并循环里的加锁、偏向锁为什么在 JDK 25 已彻底移除。附 PrintFlagsFinal、UseBiasedLocking 报错与 LockingMode 弃用的本机真实输出。</description></item><item><title>《Java 并发编程·线程与内存模型》4.2 synchronized 的字节码与对象头</title><link>https://plumephp.com/java-conc-basic-04-2-synchronized-bytecode/</link><pubDate>Wed, 28 Oct 2026 20:13:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-04-2-synchronized-bytecode/</guid><description>用 javap 拆开 synchronized：同步方法靠 ACC_SYNCHRONIZED 标志，同步块生成 monitorenter/monitorexit 与异常表；再讲对象头 Mark Word 的锁状态、可重入计数，以及锁错对象、锁字符串常量这几类真实错误。</description></item><item><title>《Java 并发编程·线程与内存模型》4.1 volatile 的语义与边界</title><link>https://plumephp.com/java-conc-basic-04-1-volatile-semantics/</link><pubDate>Wed, 28 Oct 2026 20:12:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-04-1-volatile-semantics/</guid><description>用 javap 与实测把 volatile 的三重语义拆开：它保证可见性与有序性，却不保证复合原子性；同步给出 DCL 的正确写法、8 线程下 volatile 计数器仍然丢更新的真实数据，以及 volatile 数组、volatile 引用与字段内容之间的边界。</description></item><item><title>《Java 并发编程·线程与内存模型》3.3 final 字段与安全发布</title><link>https://plumephp.com/java-conc-basic-03-3-safe-publication/</link><pubDate>Wed, 28 Oct 2026 20:11:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-03-3-safe-publication/</guid><description>解释 final 字段的初始化安全保证及其前提，用 ThisEscape 反例说明构造逸出如何让 final 失效；给出静态初始化、final 字段、volatile 引用、并发容器四类安全发布方式，并划清「引用可见」与「对象内部不可变」的边界。</description></item><item><title>《Java 并发编程·线程与内存模型》3.2 happens-before 八条规则</title><link>https://plumephp.com/java-conc-basic-03-2-happens-before/</link><pubDate>Wed, 28 Oct 2026 20:10:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-03-2-happens-before/</guid><description>把 JMM 的八条 happens-before 规则逐条拆成最小代码，说明它们只约束可见性而非实际执行顺序；再用规则链推导双重检查锁定为什么必须加 volatile，给出四道「看到 A 是否一定看到 B」的推导练习与答案，并在借阅服务里用 volatile 发布不可变审计快照。</description></item><item><title>《Java 并发编程·线程与内存模型》3.1 重排序、可见性与有序性</title><link>https://plumephp.com/java-conc-basic-03-1-reordering-visibility/</link><pubDate>Wed, 28 Oct 2026 20:09:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-03-1-reordering-visibility/</guid><description>从一段停不下来的循环入手，拆开重排序、缓存可见性与有序性三个层次，说明 as-if-serial 只对单线程负责；给出无 volatile 与有 volatile 的停机标志完整程序及本机实跑输出，并说明这类 bug 为何依赖 JIT、CPU 与运行时长方能显现。</description></item><item><title>《Java 并发编程·线程与内存模型》2.3 用 JCStress 复现计数器竞态</title><link>https://plumephp.com/java-conc-basic-02-3-jcstress-race/</link><pubDate>Wed, 28 Oct 2026 20:08:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-02-3-jcstress-race/</guid><description>用 JCStress 0.16 把计数器竞态变成可重复的统计结果：完整给出 LostUpdate 与 AtomicCounter 两个测试类，解释五个注解、ACCEPTABLE/FORBIDDEN 与结果表读法，并贴出 Apple M1 Pro 上两次 quick 模式的真实输出，说明 FORBIDDEN 触发 AssertionError 是预期行为。</description></item><item><title>《Java 并发编程·线程与内存模型》2.2 线程安全的四类策略</title><link>https://plumephp.com/java-conc-basic-02-2-safety-strategies/</link><pubDate>Wed, 28 Oct 2026 20:07:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-02-2-safety-strategies/</guid><description>把同一个有竞态的借阅服务分别用不可变对象、synchronized、ThreadLocal 和 ConcurrentHashMap 改写，逐项比较代价与失效场景，并给出一张按共享可变性、状态大小和读写比选型的矩阵，说明并发容器的复合操作为何仍然不安全，最后给出单机、多实例与跨 key 场景下的取舍。</description></item><item><title>《Java 并发编程·线程与内存模型》2.1 竞态的三种形态</title><link>https://plumephp.com/java-conc-basic-02-1-race-forms/</link><pubDate>Wed, 28 Oct 2026 20:06:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-02-1-race-forms/</guid><description>用一个会超卖的借阅服务拆解竞态的三种形态：check-then-act、read-modify-write 与发布逸出。给出完整的 UnsafeLoanService 和 32 线程复现程序，并解释为什么这类测试不稳定、跑绿也不能证明线程安全，以及库存没变负时超卖仍然可能发生。</description></item><item><title>《Java 并发编程·线程与内存模型》1.3 生命周期、优先级与守护线程</title><link>https://plumephp.com/java-conc-basic-01-3-lifecycle-daemon/</link><pubDate>Wed, 28 Oct 2026 20:05:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-01-3-lifecycle-daemon/</guid><description>六个线程状态不是文档里的名词，而是 jstack 里能对上的现场：用 latch 与监视器构造 NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED 并贴实测输出，解释 BLOCKED 与 WAITING 的排障差异，再说明优先级不可靠与守护线程退出时 finally 不执行的边界。</description></item><item><title>《Java 并发编程·线程与内存模型》1.2 Thread、Runnable、Callable 与任务抽象</title><link>https://plumephp.com/java-conc-basic-01-2-task-abstraction/</link><pubDate>Wed, 28 Oct 2026 20:04:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-01-2-task-abstraction/</guid><description>把任务从执行器中拆出来：对比 Runnable 与 Callable 的签名差异，用完整 TaskProbe 演示 submit 取回 Optional 结果、Future.get 阻塞、ExecutionException 包装，追踪裸线程、execute 与 submit 三条异常路径，并给出可命名的 ThreadFactory。</description></item><item><title>《Java 并发编程·线程与内存模型》1.1 从进程到线程：JVM 线程模型</title><link>https://plumephp.com/java-conc-basic-01-1-thread-model/</link><pubDate>Wed, 28 Oct 2026 20:03:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-01-1-thread-model/</guid><description>从进程地址空间与栈讲起，说明 JVM 平台线程与内核线程 1:1 映射的代价，给出完整 ThreadProbe 类、2000 个线程的创建耗时、threadId 等元信息，以及 jcmd Thread.print 的逐行读法，最后列出创建线程时最常见的四个坑。</description></item><item><title>《Java 并发编程·线程与内存模型》目录与学习路径</title><link>https://plumephp.com/java-conc-basic-toc/</link><pubDate>Wed, 28 Oct 2026 20:02:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-toc/</guid><description>《Java 并发编程·线程与内存模型》全书导航：说明卷一在三卷本中的位置、四个部分与十五章的依赖关系，给出顺序通读、症状驱动、源码对照三条学习路径，并按部分列出 45 节完整索引、章间依赖、全书实验清单与六个常见误区，便于按症状跳读或按章顺序通读。</description></item><item><title>《Java 并发编程·线程与内存模型》前言：环境、项目与读法</title><link>https://plumephp.com/java-conc-basic-preface/</link><pubDate>Wed, 28 Oct 2026 20:01:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-preface/</guid><description>交代本书的运行环境与版本基线：JDK 25、Maven 3.9.12、JCStress 0.16、JMH 1.37，给出 libraryd-conc 三模块的目录与 pom 配置、领域模型完整定义、preview 开关，以及 JCStress 在 JDK 25 上必须显式配置注解处理器的实际坑。</description></item><item><title>《Java 并发编程·线程与内存模型》序：从会开线程到知道为什么</title><link>https://plumephp.com/java-conc-basic-foreword/</link><pubDate>Wed, 28 Oct 2026 20:00:00 +0800</pubDate><guid>https://plumephp.com/java-conc-basic-foreword/</guid><description>《Java 并发编程·线程与内存模型》开篇：从一次库存超卖事故出发，说明「会开线程、懂规则、能判断」三个能力层次，交代 libraryd-conc 的借阅主线、conc-core/conc-lab/conc-ops 三个模块、三卷分工，以及本书不承诺的内容和最小可运行闭环。</description></item></channel></rss>