REJAVA / LEARNING NOTES
JDK 官方文档摘录:监视器 · happens-before · 偏向锁参数 · 虚拟线程(2026-09-28)
保留官方材料的来源与原文,区分接口保证和特定版本的实现。
根据课程材料整理
本次更新说明
- 整理官方依据,保留来源、版本和原文。
来源:本机已安装 JDK 自带的官方文档(
man/man1/java.1手册页、lib/src.zip中的 Javadoc 源码)。 这些文字与 Oracle / OpenJDK 在线文档同源;因沙箱无法访问 docs.oracle.com / openjdk.org,改从本机 JDK 直接摘录。 以下引文均为原文照录(仅去掉 troff / Javadoc 排版标记),中文为本工作区的对照翻译。
| 编号 | 文件 | 对应在线文档 |
|---|---|---|
| A | JDK 17(Azul Zulu 17.0.14)man/man1/java.1 | https://docs.oracle.com/en/java/javase/17/docs/specs/man/java.html |
| B | JDK 21(Temurin 21.0.10)man/man1/java.1 | https://docs.oracle.com/en/java/javase/21/docs/specs/man/java.html |
| C | JDK 21 lib/src.zip!/java.base/java/lang/Object.java | https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Object.html#notify() |
| D | JDK 21 lib/src.zip!/java.base/java/util/concurrent/package-info.java | https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/package-summary.html#MemoryVisibility |
| E | JDK 21 lib/src.zip!/java.base/java/util/concurrent/locks/ReentrantLock.java | https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/concurrent/locks/ReentrantLock.html |
| F | JDK 21 lib/src.zip!/java.base/java/lang/Thread.java | https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Thread.html#virtual-threads |
| G | JDK 21 / JDK 25 lib/src.zip!/java.base/jdk/internal/vm/Continuation.java(内部 API,仅作旁证) | — |
A. JDK 17 手册:偏向锁参数属于「已废弃」选项
DEPRECATED JAVA OPTIONS
These
javaoptions are deprecated and might be removed in a future JDK release. They’re still accepted and acted upon, but a warning is issued when they’re used.…
-XX:+UseBiasedLockingEnables the use of biased locking. Some applications with significant amounts of uncontended synchronization may attain significant speedups with this flag enabled, but applications with certain patterns of locking may see slowdowns.By default, this option is disabled.
对照:已废弃选项「仍被接受并生效,但使用时会发出警告」。-XX:+UseBiasedLocking:启用偏向锁;存在大量无竞争同步的应用开启后可能明显提速,但某些加锁模式的应用会变慢。默认关闭。
B. JDK 21 手册:「已过时」与「已删除」选项的定义
OBSOLETE JAVA OPTIONS
These
javaoptions are still accepted but ignored, and a warning is issued when they’re used.
REMOVED JAVA OPTIONS
These
javaoptions have been removed in JDK 21 and using them results in an error of:
Unrecognized VM optionoption-name…
For the lists and descriptions of options removed in previous releases see the Removed Java Options section in:
- The
javaCommand, Release 20 [https://docs.oracle.com/en/java/javase/20/docs/specs/man/java.html]- The
javaCommand, Release 19 [https://docs.oracle.com/en/java/javase/19/docs/specs/man/java.html]- The
javaCommand, Release 18 [https://docs.oracle.com/en/java/javase/18/docs/specs/man/java.html]- …
对照:选项生命周期三段 —— deprecated(仍生效 + 警告)→ obsolete(接受但忽略 + 警告)→ removed(报错 Unrecognized VM option)。
补充观察:JDK 21 手册全文检索不到 BiasedLocking,说明它不是在 JDK 21 才删的,而是在更早版本(18–20 之一)已删除;具体版本见上面 Release 18/19/20 手册(待联网核对)。本机实测见 jdk-lab-synchronized-2026-09-28.md 实验 2。
C. Object.notify():线程成为监视器持有者的三种方式
This method should only be called by a thread that is the owner of this object’s monitor. A thread becomes the owner of the object’s monitor in one of three ways:
- By executing a synchronized instance method of that object.
- By executing the body of a
synchronizedstatement that synchronizes on the object.- For objects of type
Class,by executing a static synchronized method of that class.Only one thread at a time can own an object’s monitor.
@throws IllegalMonitorStateException if the current thread is not the owner of this object’s monitor.
对照:只有持有该对象监视器的线程才能调用本方法。成为持有者有三种方式:① 执行该对象的 synchronized 实例方法;② 执行以该对象为锁的 synchronized 语句块;③ 对 Class 类型的对象,执行该类的 static synchronized 方法。**同一时刻只有一个线程能持有一个对象的监视器。**当前线程不是持有者时抛 IllegalMonitorStateException。
D. java.util.concurrent 包说明 · Memory Consistency Properties
Chapter 17 of The Java Language Specification defines the happens-before relation on memory operations such as reads and writes of shared variables. The results of a write by one thread are guaranteed to be visible to a read by another thread only if the write operation happens-before the read operation. The
synchronizedandvolatileconstructs, as well as theThread.start()andThread.join()methods, can form happens-before relationships. In particular:
- Each action in a thread happens-before every action in that thread that comes later in the program’s order.
- An unlock (
synchronizedblock or method exit) of a monitor happens-before every subsequent lock (synchronizedblock or method entry) of that same monitor. And because the happens-before relation is transitive, all actions of a thread prior to unlocking happen-before all actions subsequent to any thread locking that monitor.- A write to a
volatilefield happens-before every subsequent read of that same field. Writes and reads ofvolatilefields have similar memory consistency effects as entering and exiting monitors, but do not entail mutual exclusion locking.- A call to
starton a thread happens-before any action in the started thread.- All actions in a thread happen-before any other thread successfully returns from a
joinon that thread.The methods of all classes in
java.util.concurrentand its subpackages extend these guarantees to higher-level synchronization. In particular:
- Actions in a thread prior to placing an object into any concurrent collection happen-before actions subsequent to the access or removal of that element from the collection in another thread.
- Actions in a thread prior to the submission of a
Runnableto anExecutorhappen-before its execution begins. Similarly forCallablessubmitted to anExecutorService.- Actions taken by the asynchronous computation represented by a
Futurehappen-before actions subsequent to the retrieval of the result viaFuture.get()in another thread.- Actions prior to “releasing” synchronizer methods such as
Lock.unlock,Semaphore.release, andCountDownLatch.countDownhappen-before actions subsequent to a successful “acquiring” method such asLock.lock,Semaphore.acquire,Condition.await, andCountDownLatch.awaiton the same synchronizer object in another thread.- (Exchanger、CyclicBarrier / Phaser 两条略)
@jls 17.4.5 Happens-before Order
对照(第一组,面试常用):
- 程序顺序:线程内,程序顺序在前的动作 happens-before 在后的动作。
- 监视器锁:对一个监视器的解锁(退出 synchronized 块或方法)happens-before 随后对同一个监视器的每一次加锁(进入 synchronized 块或方法)。又因为 happens-before 可传递,一个线程解锁前的所有动作,happens-before 任何线程随后加锁之后的所有动作。
- volatile:对 volatile 字段的写 happens-before 随后对同一字段的读。volatile 读写有与进出监视器相似的内存一致性效果,但不涉及互斥加锁。
- 线程启动:对线程调用
starthappens-before 被启动线程中的任何动作。 - 线程终止:线程中的所有动作 happens-before 其他线程从该线程的
join成功返回。
第二组(学习线程池、并发容器时使用):并发容器、Executor 提交、Future.get、Lock/Semaphore/CountDownLatch 等同样建立 happens-before。
E. ReentrantLock 类说明(第一句)
A reentrant mutual exclusion
Lockwith the same basic behavior and semantics as the implicit monitor lock accessed usingsynchronizedmethods and statements, but with extended capabilities.
对照:一种可重入的互斥锁,基本行为和语义与 synchronized 方法/语句使用的隐式监视器锁相同,但扩展了更多能力。
F. Thread 类说明(JDK 21):平台线程与虚拟线程
Platform threads
Threadsupports the creation of platform threads that are typically mapped 1:1 to kernel threads scheduled by the operating system. Platform threads will usually have a large stack and other resources that are maintained by the operating system. Platforms threads are suitable for executing all types of tasks but may be a limited resource.
Virtual threads
Threadalso supports the creation of virtual threads. Virtual threads are typically user-mode threads scheduled by the Java runtime rather than the operating system. Virtual threads will typically require few resources and a single Java virtual machine may support millions of virtual threads. Virtual threads are suitable for executing tasks that spend most of the time blocked, often waiting for I/O operations to complete. Virtual threads are not intended for long running CPU intensive operations.Virtual threads typically employ a small set of platform threads used as carrier threads. Locking and I/O operations are examples of operations where a carrier thread may be re-scheduled from one virtual thread to another. Code executing in a virtual thread is not aware of the underlying carrier thread.
Thread.ofVirtual() 的 Javadoc 标注 @since 21。
对照:平台线程通常 1:1 映射到操作系统调度的内核线程,资源较重、数量有限。虚拟线程通常是由 Java 运行时(而非操作系统)调度的用户态线程,资源占用少,一个 JVM 可支撑数百万个;适合大部分时间在阻塞(如等 I/O)的任务,不适合长时间 CPU 密集计算。虚拟线程通常使用一小组平台线程作为载体线程(carrier threads);加锁和 I/O 是载体线程可能被重新调度给另一个虚拟线程的典型时机。
G. Continuation.Pinned(内部 API,仅作旁证)
JDK 21:
public enum Pinned {
/** Native frame on stack */ NATIVE,
/** Monitor held */ MONITOR,
/** In critical section */ CRITICAL_SECTION }
JDK 25:
public enum Pinned {
/** Native frame on stack */ NATIVE,
/** Monitor held */ MONITOR,
/** In critical section */ CRITICAL_SECTION,
/** Exception (OOME/SOE) */ EXCEPTION
}
说明:JDK 21 源码中虚拟线程无法让出载体线程(pinned)的原因之一是 MONITOR(持有监视器)。JDK 25 仍保留该枚举值,所以不能仅凭源码推断「JDK 25 已完全消除 synchronized 导致的钉住」;行为差异以本机实测(jdk-lab-synchronized-2026-09-28.md 实验 3)为准,机制与修复版本以 OpenJDK JEP 原文为准(待联网核对)。