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

final 字段:为什么构造完成后有特殊可见性

验证 final 字段的可见性保证:构造器里 this 逃逸时另一个线程读到 final 字段是默认值 0;反射可以修改实例 final 字段,编译期常量会被内联而读不到新值,static final 与 record 字段则抛 IllegalAccessException;用 jcstress 做数据竞争发布,final 与普通字段在这台机器上都没有读到默认值(无法区分)。

Java final 字段 安全发布 jcstress 真实验证 动画演示
Java 内部原理 2026-10-02

安全发布:对象构造完成后如何被其它线程正确看到

验证对象的几种发布方式:普通静态字段发布的对象,JIT 热循环里的读线程 3 秒仍看不到;volatile、AtomicReference、synchronized getter、ConcurrentHashMap 约 207 ms 后都看到了完整的对象;Thread.start、Thread.join 与类初始化器发布不需要额外同步。

Java 安全发布 可见性 volatile 真实验证 动画演示
Java 内部原理 2026-10-02

HttpClient:连接复用、异步请求和 HTTP/2

用 JDK 21 的 HttpClient 对 nginx(TLS 端口 HTTP/2、明文端口 HTTP/1.1)做实测:偏好 HTTP_2 访问明文端口退回 HTTP_1_1;同一个 HttpClient 20 个请求用 1 个连接、每次新建用 20 个;50 个并发请求 HTTP/2 只用 1 个连接、HTTP/1.1 用 50 个;超时与取消的异常。

Java HttpClient HTTP/2 连接复用 nginx 真实验证 动画演示
Java 内部原理 2026-10-02

JSSE TLS 握手:Java 如何验证证书和协商密钥

用 JDK 21 的 JSSE 做真实的 TLS 实验:协商出 TLSv1.3 与 TLS_AES_256_GCM_SHA384;自签名证书不在信任库、主机名不符、CA 签发的证书过期时分别抛出什么错误;协议版本没有交集时 protocol_version 告警;同一个 SSLContext 的会话复用;javax.net.debug 里的握手消息顺序。

Java JSSE TLS 证书 握手 真实验证 动画演示
Java 内部原理 2026-10-02

JAR 文件:manifest、签名和多版本 JAR

真实验证 JAR:Main-Class 缺失时的报错、java -jar 不使用外部类路径;Class-Path 相对 jar 位置、manifest 每行最多 72 字节自动折行;jarsigner 签名增加 .SF 与 .EC,篡改 class 后 SHA-384 digest error;多版本 JAR 在 JDK 17、21、27 上分别选 versions/17、21、21 的实现。

Java JAR manifest jarsigner 多版本 JAR 真实验证 动画演示
Java 内部原理 2026-10-02

正则表达式:回溯引擎为什么会灾难性回溯

在 JDK 21 上实测正则回溯:经典的 (a+)+b 等贪婪写法已经不会指数爆炸,但懒惰量词、(.*a){12}、带反向引用的模式仍然每多 4 个字符慢十几倍,n = 28 超过 2 秒;原子组、占有量词或改写模式可以解决;(a|b)* 对 4000 字符的输入栈溢出,[ab]* 不会;用自定义 CharSequence 给匹配加截止时间。

Java 正则表达式 回溯 ReDoS 真实验证 动画演示
Java 内部原理 2026-10-02

Formatter:格式化字符串背后的解析过程

真实运行 String.format:说明符语法(宽度、补零、千分位、%x、%e、%b、%c)、舍入是 HALF_UP(%.0f 把 2.5 变成 3)、八种出错异常、Locale 对千分位与小数点(de_DE 的 1.234.567 / 1234,50)和大写(土耳其语 i → İ)的影响、参数序号 %2$s 与 %<s、Formattable。

Java Formatter String.format Locale 真实验证 动画演示
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 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号