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,能够显著提升并发性能。
相关推荐
数据知道20 小时前
Go语言:加密与解密详解
开发语言·后端·golang·go语言
武子康20 小时前
大数据-117 - Flink JDBC Sink 详细解析:MySQL 实时写入、批处理优化与最佳实践 写出Kafka
大数据·后端·flink
Stream_Silver20 小时前
LangChain入门实践3:PromptTemplate提示词模板详解
java·python·学习·langchain·language model
小树懒(-_-)20 小时前
SEO:Java项
java·开发语言
用户214118326360221 小时前
Qwen3-VL 接口部署全攻略:从源码到 Docker,手把手教你玩转多模态调用
后端
TeleostNaCl21 小时前
如何在 IDEA 中使用 Proguard 自动混淆 Gradle 编译的Java 项目
android·java·经验分享·kotlin·gradle·intellij-idea
小蕾Java21 小时前
IntelliJ IDEA 2025:最新使用图文教程!
java·ide·intellij-idea
聪明的笨猪猪21 小时前
Java “线程池(1)”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
Miraitowa_cheems21 小时前
LeetCode算法日记 - Day 63: 图像渲染、岛屿数量
java·数据结构·算法·leetcode·决策树·贪心算法·深度优先
databook21 小时前
Manim实现旋转扭曲特效
后端·python·动效