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,能够显著提升并发性能。
相关推荐
Java牛马7 小时前
SpringBoot Starter 依赖相关总结
java·spring·springboot·starter·自动装配·依赖
吴声子夜歌7 小时前
Java面试——Spring Cloud原理及应用(二)
java·spring cloud·面试
SomeB1oody7 小时前
【RustyML入门】6.3. 并行归约
开发语言·后端·机器学习·rust·教程
东小西7 小时前
【SAA实战】第 1 篇:ReactAgent 入门——先撸个"会调工具的助手"跑起来
java·人工智能·spring
Profile排查笔记8 小时前
指纹浏览器哪个好?从 Profile、代理、权限和自动化能力判断是否适合
前端·人工智能·后端·自动化
用户938515635078 小时前
用 AI 结对编程从 0 搭一个"单词后台管理系统":Next.js + Supabase + Drizzle + shadcn/ui 全记录
后端·postgresql·next.js
mqiqe8 小时前
AgentScope Java 2.0 协议集成全景解析:A2A、AG-UI、Agent Protocol 三大开放协议实战指南
java·开发语言·ui
脉动数据行情8 小时前
Java 实现台股 TWSE/TPEx 行情采集(个股 + K 线)
java·开发语言·twse·tpex·台股
爱学习的小邓同学9 小时前
Golang --- (1)第一个Golang程序
开发语言·后端·golang
小灰灰搞电子10 小时前
Rust+Slint 实现的“DNA双螺旋”加载动画源码分享
后端·rust·slint·加载动画