本期检索说明

先读取 content/collections/deep-radar 截至 2026-09-15 的全部原文链接,并按 URL、标题与机制语义去重。最近 24 小时内,OpenJDK 的 Exchanger 修复给出四种平台、平台线程/虚拟线程、完整分位数与 JMH 源码;Tokio 的外部任务注入队列分片则给出 1–64 个并发提交线程的阶梯 benchmark、完整数据结构补丁以及停车协议的内存可见性说明。两项都覆盖“实测数据、源码证据、原理剖析”三项硬指标。

Kotlin/Native 的全局优化候选报告了单一工程中反虚拟化分析内存从约 3GB 降至 600MB,但缺少多工作负载矩阵;Zig 当日没有新的一手候选,Linux 新材料也没有形成同等证据闭环,因此不凑数。本期两项都仍是开放 PR;文中分析公开实验与实现,不把它们写成已发布或默认启用的能力。

主题 原始发布日期 一手来源与交叉验证 截稿状态 推荐强度
Java Exchanger 以有限自旋摊薄 park/unpark 2026-09-15 23:37(中原标准时间) OpenJDK PR #32886 / JDK-8391552 / Webrev / 新增 JMH Open,已有核心并发维护者正向意见,尚未合入 必读
Tokio 外部任务注入队列分片 2026-09-16 05:52(中原标准时间) Tokio PR #8483 / 64 核 benchmark / 完整队列与测试补丁 Open,默认关闭、unstable opt-in 必读

01 · OpenJDK:用有限自旋摊薄 park/unpark,找回 Exchanger 的配对吞吐

原文与日期: Viktor Klang,2026-09-15 23:37(中原标准时间);OpenJDK PR #32886JDK-8391552Webrev。截稿时补丁修改 2 个文件、增加 117 行、删除 1 行,尚未正式合入。

为什么值得读: 这是一个“一行常量背后需要完整平台矩阵”的并发性能案例。Exchanger 只负责让两个线程在 rendezvous 点交换对象,但等待策略会决定高频配对究竟停留在用户态,还是反复进入昂贵的内核 park/unpark。JDK 24 之后 macOS 的 pairwise handoff 出现约 27 倍回退;修复本身只是提高有限自旋上限,证据却必须覆盖不同 CPU、OS 与线程实现。

核心技术结论: Exchanger 的 arena slot 没有立即匹配时,线程会先忙等一段时间,随后阻塞或尝试收缩 arena。旧常量为 1 << 10,也就是 1024 次自旋;在对端很快到达、但 1024 次不足以跨过调度与可见性窗口的场景中,双方会频繁支付 park/unpark。补丁把上限提高到 24576:

Java
// 等待匹配,之后才阻塞或收缩 arena
private static final int SPINS = 24576;

24576 等于 (1 << 13) | (1 << 14)。作者尝试过多种静态和动态估算后,选择它作为目前最好的折中;Doug Lea 的评审意见指出,高自旋只在高度竞争的使用方式下触发,低核心数或超额订阅系统通常不会持续付出全部成本。不过这仍是经验参数,所以 PR 同时新增仓库内 JMH,让未来架构和调度器变化可以重新调优,而不是把数字永久神秘化。

最有价值的实验、源码与 benchmark 细节: 新增的 Exchangers benchmark 使用 Mode.SampleTime、5×5 秒预热、5×5 秒测量,参数覆盖 10/100/1000 次交换以及平台线程/虚拟线程。每次 invocation 创建一个对端任务,以 CountDownLatch 同步起跑,两端循环调用同一个 Exchanger.exchange,从而直接测量配对延迟而不是线程池吞吐。

相对当前 mainline,macOS AArch64 上 1000 次平台线程交换由 1,836,259.661 ± 4,259.901 ns/op 降到 103,016.295 ± 135.726,提升 17.82 倍;虚拟线程由 1,979,030.192 ± 29,860.479 降到 84,552.808 ± 51.378 ns/op,提升 23.51 倍。虚拟线程中位数从 2,703,360 ns 降至 83,200 ns,约 32.5 倍;p99 从 2,822,144 降到 124,800 ns,约 22.6 倍。

跨平台结果阻止了“所有机器都会快 20 倍”的错误结论。Linux AArch64 平台线程约 329,692 → 332,159 ns/op,Linux x64 约 173,516 → 177,661,都近似持平;Windows x64 平台线程约改善 1.17 倍,虚拟线程基本持平。macOS 平台线程相对 JDK 21 基线也只是 97,160 → 103,016 ns/op,说明修复的目标是恢复历史水平,不是创造普遍数量级提升。

尾延迟还显示了自旋参数的风险:Linux AArch64 虚拟线程的最大值从约 4.48ms 放大到 147.59ms,尽管主体分位接近;macOS 的最大值也不随平均值等比例改善。PR 尚未合入,合理的工程结论是“显著修复 macOS 主体分布、其它平台大体中性”,不能把偶发最大值忽略后宣称全面无回退。

适合的工程师背景: 维护高频线程交接、无锁队列、虚拟线程运行时或低延迟 Java 服务,并熟悉 JMH 分位数与 park/unpark 成本的工程师。

预计阅读收益: 约 50–75 分钟;能理解 rendezvous 原语为何对自旋阈值极其敏感,学会用跨 OS、跨架构与全分位矩阵评估“一行常量”优化,并看到如何把调参依据固化成可持续 benchmark。

02 · Tokio:把远端 spawn 的全局互斥锁拆成最多 16 个队列分片

原文与日期: alex,2026-09-16 05:52(中原标准时间);Tokio PR #8483。截稿时补丁修改 10 个文件、增加 647 行、删除 109 行,功能默认关闭,只能通过 tokio_unstable builder 方法或环境变量试用。

为什么值得读: Tokio 多线程调度器擅长从 worker 本地队列执行任务,但 runtime 外部线程调用 spawn 时,需要把任务注入共享队列。单个全局 mutex 在低并发下简单高效,在几十个外部 producer 同时提交时却把所有线程串行化。这份补丁不仅“加分片”,还处理了批量弹出、公平扫描、关闭语义、false sharing 和 worker 停车协议,展示了并发数据结构优化真正困难的边界。

核心技术结论: 新的 ShardedInject 根据 worker 数取二次幂,最多创建 16 个 shard;每个 shard 拥有独立 Mutex<Synced>、链表状态和长度原子,并用 CachePadded 隔离缓存行。外部线程第一次访问时随机选择一个 sticky shard,之后一直向同一 shard 推送:不同 producer 大概率分散锁竞争,同一 producer 的批量任务又保持聚集,worker 一次 pop_n 更容易拿到连续 batch。

Rust
let num_shards = num_workers.next_power_of_two().min(MAX_SHARDS);

// 每个线程固定到一个随机分片
fn push_shard(&self) -> usize {
    thread_shard_value() % self.shards.len()
}

读取侧从自身 sticky shard 开始环形扫描,既分散多个 worker 的抢锁起点,又保证最终覆盖所有 shard。pop_n 可以跨多个 shard 填满目标批次,第一项直接返回执行,其余推入 worker 本地 run queue。队列关闭时逐 shard 关闭;最后一个 shard 的关闭状态作为“所有 shard 已完成关闭”的发布点,确保 shutdown drain 不会与仍可接受任务的分片交错。

最关键的设计不是 shard 数,而是 non_empty_mask。Tokio worker 准备停车时需要一次无锁的“是否还有工作”复查;若逐个读取多个长度原子,push 可能从扫描过的 shard 滑到尚未扫描的 shard,形成不一致快照。补丁用一个 AtomicUsize 的每位表示对应 shard 非空,使 is_empty 仍然只需单次 load:

Rust
pub(crate) fn is_empty(&self) -> bool {
    self.non_empty_mask.load(Relaxed) == 0
}

位图只在持有相应 shard 锁时根据空/非空转换更新;batch push 先释放 shard 锁再置位,但保证在随后的 worker 通知之前完成,因此保持原停车/唤醒顺序。这里使用 Relaxed 不是忽视可见性,而是任务链表内容仍由 mutex 发布,位图承担候选提示和单快照判空,不替代队列本身的同步。

最有价值的实验、源码与 benchmark 细节: 64 核机器上的 benches/remote_spawn.rs 显示,1 个提交线程新旧均为 7.90ms,证明低竞争路径没有基准可见成本;2 线程从 11.41ms 降至 7.81ms(1.46×),4 线程从 20.70ms 降至 6.65ms(3.11×),8 线程从 32.51ms 降至 6.30ms(5.16×)。32 线程达到最佳相对提升:30.16 → 5.28ms,快 5.71 倍;64 线程为 27.85 → 5.04ms,快 5.53 倍。

补丁把共享队列抽象成 Locked/Sharded 两种实现,复用原链表的 push、batch、pop 与 close 逻辑,并新增普通单元测试和 loom 下的确定性分片选择。负向边界也写在源码里:taskdump 的跨 shard drain_into 不是整体原子操作,并发 push 可能落入已经扫过的 shard;tracer 能容忍它,因为这类任务已经处于 notified 状态。分片方案目前默认关闭,说明 64 核 remote-spawn 胜利还不足以替代更广泛的真实工作负载和调度公平性验证。

适合的工程师背景: 维护 Tokio 高并发网关、跨线程任务提交器、work-stealing scheduler,或正在设计分片队列和停车协议的 Rust 工程师。

预计阅读收益: 约 70–100 分钟;能看到如何从 mutex 火焰图走到 sticky sharding,理解单原子非空位图为何是停车正确性的一部分,并掌握分片队列的关闭、批量弹出、缓存行和追踪一致性权衡。

中国大陆 ToC 硬件价格观察

数据口径

窗口为 2026-08-18 至 2026-09-16,单位人民币。六类硬件继续固定同一 SKU。9 月 16 日实际请求六个固定样本页:CPU、GPU、主板、HDD 与 SSD 页面超时,DRAM 页面明确显示暂无报价,因此没有任何类别取得同日、同型号、同渠道且可复核的新价格。本期不新增 JSON 数据点,也不把旧值复制成今日行情;折线的空白尾段表示证据缺失而不是横盘。

中国大陆六类 PC 硬件公开价格事件

类别 固定样本与最后可复核价 30 日窗口内真实走势 建议
CPU Ryzen 7 9800X3D,最后可核验 9/15 ¥2,619 8/21 ¥2,609 → 9/9 ¥2,449 → 9/14 ¥2,639 → 9/15 ¥2,619 观望;¥2,449–2,599 可作为关注区间,付款前重新核验渠道价
GPU MSI RTX 5070 VENTUS 3X 12G,最后可核验 9/13 ¥4,464.34 8/29–9/13 六个真实采集点均为 ¥4,464.34 继续观望;样本新鲜度开始下降,不能把空白尾段解释为横盘
主板 ASUS TUF B850M-PLUS WIFI7,最后可核验 9/8 ¥1,299 8/31 ¥1,449 → 9/2–9/8 ¥1,299,随后缺少新点 刚需可关注 ¥1,299;付款前重核 WIFI7 版本与售后
DRAM Kingston FURY Beast DDR5-6000 32GB,最后可核验 9/9 ¥3,900 9/2 ¥3,900,9/5 ¥3,860,随后回到 ¥3,900;今日页面暂无报价 观望;没有连续下跌证据,也没有今日可购价格
HDD IronWolf Pro 8TB ST8000NE001,最后可核验 9/10 ¥1,849 9/1–9/10 五个真实点均为 ¥1,849 按容量刚需购买;下单前比较五年保修与数据恢复服务
SSD ZHITAI Ti600 2TB,最后可核验 9/10 页面最低 ¥749 9/2 ¥1,919 → 9/5–9/10 ¥749;同页渠道价差异常大 谨慎核验后入手;先确认容量、颗粒、保修与商家

价格来源: 9800X3DMSI RTX 5070 VENTUS 3XASUS TUF B850M-PLUS WIFI7Kingston FURY DDR5-6000 32GBIronWolf Pro 8TBZHITAI Ti600 2TB

判断依据

今天没有新增价格事实,因此不根据缺失数据更新涨跌判断。CPU 最近一次从低点反弹后小幅回落,GPU、主板、DRAM、HDD 与 SSD 的末点则已有 3–8 天延迟;越旧的数据越只适合提供历史参照,而不适合作为直接下单依据。SSD 的 ¥749 继续视为需要核验规格和渠道的异常事件,不能外推为 2TB SSD 全市场价格。

其它你可能关心的

本期结论

两篇材料处理的是同一种扩展性断点:当并发度提高,原本“足够便宜”的阻塞或全局锁开始主导成本。OpenJDK 用更长但有限的用户态等待避免过早进入内核,Tokio 用分片把外部 producer 从一把锁上拆开;前者必须防止耗尽 CPU 和恶化尾延迟,后者必须维护停车快照与关闭语义。工程上最值得迁移的不是 24576 或 16 这两个数字,而是用完整并发梯度、跨平台矩阵和负向指标来限定优化的适用范围。