除了 synchronized 之外,Java 中还有哪些内置锁(即 JVM 原生支持、无需依赖 JUC 包的锁机制),区别于 ReentrantLock 这类显式锁,而是 JDK 本身内置的、语言层面/核心类库原生支持的锁能力。
首先明确:synchronized 是 Java 最核心的内置锁(监视器锁),除此之外,Java 内置的锁机制主要体现在Object 类的等待/唤醒机制(与 synchronized 配合)、隐式的内置锁语义,以及 JDK 底层隐含的锁能力,具体如下:
这不是独立的锁,但属于 Java 内置的、与 synchronized 绑定的同步协作机制,是内置锁的重要补充:
wait()/notify() 必须在 synchronized 代码块/方法中调用(持有对象的监视器锁),本质是对内置锁的“等待-唤醒”扩展;示例代码:
public class ObjectWaitNotifyDemo {
privatefinal Object lock = new Object();
privateboolean hasData = false;
// 生产者
public void produce() {
synchronized (lock) { // 持有内置锁
while (hasData) {
try {
lock.wait(); // 释放锁并等待,必须在synchronized内调用
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
System.out.println("生产者生产数据");
hasData = true;
lock.notify(); // 唤醒等待的消费者线程
}
}
// 消费者
public void consume() {
synchronized (lock) { // 持有内置锁
while (!hasData) {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
System.out.println("消费者消费数据");
hasData = false;
lock.notify(); // 唤醒等待的生产者线程
}
}
public static void main(String[] args) {
ObjectWaitNotifyDemo demo = new ObjectWaitNotifyDemo();
// 启动生产者线程
new Thread(demo::produce, "生产者").start();
// 启动消费者线程
new Thread(demo::consume, "消费者").start();
}
}
static synchronized 修饰的方法,锁定的是类对象(Class 实例),而非实例对象,属于 synchronized 的内置锁变体,也是 Java 原生支持的:
synchronized 锁定 this,静态方法的 synchronized 锁定 Xxx.class;示例代码:
public class StaticBuiltInLockDemo {
privatestaticint staticCount = 0;
// 静态内置锁:锁定 StaticBuiltInLockDemo.class
public static synchronized void staticIncrement() {
staticCount++;
System.out.println("静态锁:" + staticCount);
}
// 实例内置锁:锁定 this
public synchronized void instanceIncrement() {
System.out.println("实例锁:" + Thread.currentThread().getName());
}
}
Java 核心类库中的不可变对象(如 String、Integer、Long),其不可变特性带来了“天然线程安全”,相当于 JVM 内置了“无锁的同步保障”:
所有 Java 类的 Class 实例(如 String.class、Object.class)都自带监视器锁,除了 static synchronized 会用到,也可直接作为 synchronized 代码块的锁定对象,属于 JVM 内置的锁载体:
public class ClassBuiltInLockDemo {
public void doSomething() {
// 锁定 Class 对象的内置监视器锁
synchronized (ClassBuiltInLockDemo.class) {
System.out.println("持有 Class 内置锁");
}
}
}
很多开发者会误以为以下机制是“内置锁”,但实际上它们不属于 Java 语言/ JVM 内置,而是基于 JUC 包的显式锁:
ReentrantLock/ReentrantReadWriteLock:JUC 提供的显式锁,需手动 lock()/unlock(),不是内置锁;StampedLock:JDK 1.8 新增的显式锁,属于 JUC 组件;Atomic* 原子类:基于 CAS 的无锁机制,并非“锁”,而是原子操作;ConcurrentHashMap):底层依赖 CAS/分段锁,但属于类库实现,不是语言层面的内置锁。Java 中除了核心的 synchronized 内置监视器锁外,真正属于“内置锁”范畴的是:
Java 没有除 synchronized 外的“独立内置锁关键字/机制”,所有内置锁能力都围绕 synchronized(监视器锁)展开,而 ReentrantLock 等属于显式锁,并非内置锁。