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,能够显著提升并发性能。
相关推荐
寻星探路35 分钟前
【深度长文】万字攻克网络原理:从 HTTP 报文解构到 HTTPS 终极加密逻辑
java·开发语言·网络·python·http·ai·https
想用offer打牌2 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
曹牧3 小时前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
KYGALYX3 小时前
服务异步通信
开发语言·后端·微服务·ruby
掘了3 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
爬山算法4 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
kfyty7254 小时前
集成 spring-ai 2.x 实践中遇到的一些问题及解决方案
java·人工智能·spring-ai
猫头虎4 小时前
如何排查并解决项目启动时报错Error encountered while processing: java.io.IOException: closed 的问题
java·开发语言·jvm·spring boot·python·开源·maven
李少兄4 小时前
在 IntelliJ IDEA 中修改 Git 远程仓库地址
java·git·intellij-idea
Moment4 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端