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,能够显著提升并发性能。
相关推荐
兔子撩架构4 分钟前
Akka Cluster的整体应用:系统管理的核心支撑
java·架构
毕设源码-李学长8 分钟前
计算机毕业设计java高校多媒体教室管理系统高校多媒体教室综合管理系统高校智能多媒体教室管理平台
java·开发语言·课程设计
AAA修煤气灶刘哥8 分钟前
从 Timer 到 XXL-Job,定时任务调度的 “进化史”,看完再也不怕漏跑任务~
java·后端·架构
zjjuejin9 分钟前
Docker Swarm 完全指南:从原理到实战
后端·docker
shark_chili9 分钟前
深入GPU核心:理解现代并行计算的硬件架构
后端
乘风破浪酱5243610 分钟前
MyBatis-Plus UserMpper接口示例
后端
无奈何杨15 分钟前
风控系统的事中与事后一致性与闭环
前端·后端
这里有鱼汤20 分钟前
为什么指数涨你却亏钱?80%的人忽略的市场宽度指标揭晓,我用Python实现了(附源码)
后端·python
ss27331 分钟前
基于Springboot + vue实现的高校大学生竞赛项目管理系统
vue.js·spring boot·后端
念念010731 分钟前
Flask 博客系统(Flask Blog System)
后端·python·flask