知其然,知其所以然
Java 内部原理 2026-10-02

ScopedValue:为什么它比 ThreadLocal 更适合上下文传递

在 JDK 27 上验证 ScopedValue:绑定只在 where().run 范围内有效、嵌套可重新绑定、异常也会解除、没有 set;线程池里 ThreadLocal 忘了 remove 会泄漏给下一个任务而 ScopedValue 不会;不会自动传给 new Thread 启动的线程;10 万个虚拟线程时内存几乎一样(99/97/95 MB)。

Java ScopedValue ThreadLocal 虚拟线程 真实验证 动画演示
Java 内部原理 2026-10-02

Structured Concurrency:并发子任务如何统一取消和收集异常

在 JDK 27(预览 API)上验证结构化并发:两个 100 ms 的子任务并行 121 ms 完成;一个失败后 72 ms 内取消其余并抛 ExecutionException,慢任务被中断;anySuccessfulOrThrow 取第一个成功的并取消其余;withTimeout 超时抛 CancelledByTimeoutException;忘了 join 抛 IllegalStateException;子任务运行在虚拟线程。

Java 结构化并发 StructuredTaskScope 虚拟线程 真实验证 动画演示
Java 内部原理 2026-10-02

RandomGenerator:Java 随机数算法如何插拔

JDK 21 的 RandomGenerator 实测:注册了 13 个算法(默认 L32X64MixRandom);同算法同种子序列一致、换算法不同;单线程 nextLong:Random 16.98 ns、Xoroshiro128PlusPlus 3.1 ns、ThreadLocalRandom 0.87 ns、SecureRandom 132.98 ns;jump 与 split 给并行任务独立的生成器。

Java RandomGenerator 随机数 Xoshiro 真实验证 动画演示
Java 内部原理 2026-10-02

SplittableRandom:为什么适合并行任务

8 个线程下总吞吐(百万次 nextLong/秒):共享 Random 只有 2、ThreadLocalRandom 7120、每线程 split() 出来的 SplittableRandom 8339;并行蒙特卡洛 π 用 split() 的子生成器 5 次运行结果完全相同,ThreadLocalRandom 与共享 Random 互不相同;两个线程共用一个 SplittableRandom 会拿到大量重复数值。

Java SplittableRandom 并行 随机数 真实验证 动画演示
Java 内部原理 2026-10-02

SecureRandom:安全随机数如何获得熵

JDK 21 on macOS 上验证 SecureRandom:默认 NativePRNG、getInstanceStrong 是 NativePRNGBlocking;SHA1PRNG 首次使用前 setSeed 可复现而 NativePRNG/DRBG 不可复现;每次 new 比复用慢约 82 倍;100 万字节的粗略统计检查(1 的比特 0.5001)。

Java SecureRandom 熵 NativePRNG DRBG 真实验证 动画演示
Java 内部原理 2026-10-02

BigInteger:大整数加减乘除如何实现

实测 BigInteger:内部是大端 int[] 加独立的 signum;乘法在大数下耗时增长指数约 1.3~1.5(低于小学乘法的 2);toString 80 万位 236.08 ms,但 new BigInteger(String) 解析要 12880.87 ms(每翻倍约 4 倍);RSA 规模的 modPow 2048 位模数 1.5 ms、8192 位 77.3 ms。

Java BigInteger 大整数 乘法 真实验证 动画演示
Java 内部原理 2026-10-02

Files.mmap:内存映射文件如何工作

实测 FileChannel.map:映射 1 GB 文件时 RSS 只从 40 MB 涨到 44 MB,碰遍所有页后 1079 MB;随机读 100 万个 8 字节映射 15 ns/次、RandomAccessFile 1003 ns/次;映射写入对 Files.readAllBytes 立刻可见;单个映射不能超过 Integer.MAX_VALUE;READ_WRITE 映射会扩大文件。

Java 内存映射 mmap FileChannel 真实验证 动画演示
Java 内部原理 2026-10-02

WatchService:Java 如何监听文件变化

在 macOS 上实测 WatchService:实现是 PollingWatchService(轮询),创建文件到收到事件延迟约 2 秒([1.71, 1.99, 2.00] 秒),设成 HIGH 灵敏度没有变化;事件语义(重命名是 CREATE + DELETE、连续写合并、不递归);不调用 key.reset() 收不到后续事件。

Java WatchService 文件监听 NIO.2 真实验证 动画演示
Java 内部原理 2026-10-02

AsynchronousFileChannel:文件异步 I/O 的线程模型

验证 AsynchronousFileChannel 的线程模型:默认线程池里 CompletionHandler 运行在 Thread-N 守护线程上(这次出现了 17 个),不在调用线程;传入自定义线程池后 handler 运行在其上、线程池关闭后 read 抛 RejectedExecutionException;并发写到不同位置的内容全部正确。

Java AsynchronousFileChannel 异步 I/O NIO.2 真实验证 动画演示
Java 内部原理 2026-10-02

Unix Domain Socket:Java 如何进行本机进程通信

在 macOS 上实测 JDK 的 Unix 域套接字:地址是文件系统路径、关闭后文件不会自动删除、重复 bind 抛 BindException、路径太长抛 SocketException;1 字节来回 4.9 µs(TCP 回环 20.1 µs),但 2 GB 传输 1105 MB/s 低于 TCP 回环的 2105 MB/s。

Java Unix 域套接字 NIO 进程间通信 真实验证 动画演示
Java 内部原理 2026-10-02

DatagramChannel:UDP 和 TCP 的实现边界

在 macOS 回环上实测 DatagramChannel:数据报保留边界、缓冲区太小会截断并丢弃剩余;65507 字节能发、65508 字节抛 Message too long;接收方来不及读时 10 万个数据报在默认缓冲区只收到 4099 个、8 MB 缓冲区收到 34953 个;connect 之后写到没人监听的端口抛 PortUnreachableException,并只接收指定来源。

Java DatagramChannel UDP NIO 真实验证 动画演示
Java 内部原理 2026-10-02

WebSocket:Java 如何维持全双工连接

用 JDK 的 java.net.http.WebSocket 对 Netty 服务端做真实实验:握手的 101 响应与 Sec-WebSocket-Accept、文本与二进制、分片帧、服务端 ping、关闭握手;背压——不调用 request(n) 就收不到消息(0 次),request(2) 后收到 2 条;服务端主动 Close 4000。

Java WebSocket HttpClient Netty 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号