Java 锁机制对比:Synchronized、ReentrantLock、StampedLock

在并发编程中,锁机制是保证线程安全的重要手段。Java 提供了多种锁机制,从最基础的 synchronized 到功能更强大的 ReentrantLock,再到高性能的 StampedLock。本文将对三者进行系统对比,帮助你在实际开发中做出合理选择。


1. Synchronized

特点

  • Java 关键字,语法层面支持。
  • 编译器和 JVM 层面优化(锁升级:偏向锁 → 轻量级锁 → 重量级锁)。
  • 自动释放锁,无需手动 unlock。
  • 不能中断等待锁的线程。
  • 公平性不可控,默认非公平。

使用示例

java 复制代码
public synchronized void increment() {
    count++;
}

public void test() {
    synchronized (this) {
        count++;
    }
}

2. ReentrantLock

特点

  • 位于 java.util.concurrent.locks 包下。
  • 可重入,支持公平锁 / 非公平锁选择。
  • 提供 tryLock()(可超时获取锁)、lockInterruptibly()(可中断获取锁)。
  • 需要手动释放锁,必须在 finally 中调用 unlock()
  • 提供 Condition 实现精确的线程通信。

使用示例

csharp 复制代码
private final ReentrantLock lock = new ReentrantLock();

public void increment() {
    lock.lock();
    try {
        count++;
    } finally {
        lock.unlock();
    }
}

带超时:

csharp 复制代码
if (lock.tryLock(1, TimeUnit.SECONDS)) {
    try {
        // do work
    } finally {
        lock.unlock();
    }
}

3. StampedLock

特点

  • Java 8 引入,主要用于优化读多写少的场景。

  • 提供三种模式:

    • 写锁(writeLock) :独占。
    • 读锁(readLock) :共享。
    • 乐观读(tryOptimisticRead) :无锁,提升并发性能。
  • 不可重入,不支持条件变量。

  • 需要手动释放锁。

使用示例

ini 复制代码
private final StampedLock lock = new StampedLock();
private double x, y;

void move(double deltaX, double deltaY) {
    long stamp = lock.writeLock();
    try {
        x += deltaX;
        y += deltaY;
    } finally {
        lock.unlockWrite(stamp);
    }
}

double distanceFromOrigin() {
    long stamp = lock.tryOptimisticRead();
    double currentX = x, currentY = y;
    if (!lock.validate(stamp)) {
        stamp = lock.readLock();
        try {
            currentX = x;
            currentY = y;
        } finally {
            lock.unlockRead(stamp);
        }
    }
    return Math.sqrt(currentX * currentX + currentY * currentY);
}

4. 三者对比

特性 synchronized ReentrantLock StampedLock
可重入
公平锁支持
自动释放锁
可中断
条件变量
乐观读支持
性能优化 JVM 优化 AQS 实现 读多写少场景

5. 适用场景

  • synchronized:简单同步逻辑,代码可读性要求高的场景。
  • ReentrantLock:需要可中断、公平性、条件变量的复杂同步场景。
  • StampedLock:高并发、读多写少的性能敏感场景。

6. 总结

  • 如果只是简单的锁需求,synchronized 足够,且 JVM 已经做了大量优化。
  • 如果需要灵活控制锁,ReentrantLock 是首选。
  • 如果是读多写少的业务,推荐使用 StampedLock,能够显著提升并发性能。
相关推荐
yuhaiqiang16 分钟前
被 AI 忽悠后,开始怀念搜索引擎了?
前端·后端·面试
sxlishaobin40 分钟前
Java I/O 模型详解:BIO、NIO、AIO
java·开发语言·nio
二闹1 小时前
Python文件读取三巨头你该选择哪一个?
后端·python
彭于晏Yan1 小时前
Spring AI(二):入门使用
java·spring boot·spring·ai
有一个好名字1 小时前
vibe codeing 开发流程
java
兑生1 小时前
【灵神题单·贪心】3745. 三元素表达式的最大值 | 排序贪心 | Java
java·开发语言
苏三说技术1 小时前
推荐几个牛逼的AI Agent项目
后端
polaris06301 小时前
Windows操作系统部署Tomcat详细讲解
java·windows·tomcat
卓怡学长1 小时前
m280本科生导师指导平台
java·数据库·spring·tomcat·maven·intellij-idea
武子康1 小时前
大数据-253 离线数仓 - Airflow 入门与任务调度实战:DAG、Operator、Executor 部署排错指南
大数据·后端·apache hive