Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

    • Java并发概述
    • 线程与进程
    • Thread类与线程生命周期
    • 线程创建与任务模型
    • 线程安全
    • synchronized关键字
    • volatile关键字
    • Java内存模型(JMM)
    • 线程间通信
    • 线程池
    • 并发工具类
    • 原子操作类Atomic
    • 并发锁
      • 1. Lock 基本用法
      • 2. ReentrantLock
      • 3. tryLock
      • 4. lockInterruptibly
      • 5. 公平锁与非公平锁
      • 6. Condition
      • 7. ReadWriteLock
      • 8. StampedLock
      • 9. AQS 简介
      • 10. 锁选型
      • 专家实践与边界
      • Tips 快问快答
    • 并发容器
    • ConcurrentHashMap
    • BlockingQueue
    • CopyOnWriteArrayList
    • ThreadLocal
    • Fork/Join框架
    • ScheduledThreadPoolExecutor
    • CompletableFuture
    • 虚拟线程
    • 死锁活锁与线程问题排查
    • 并发编程最佳实践
  • Java IO

  • JVM

  • Java
  • Java并发
Wray
2026-06-24
目录

并发锁

Java 除了 synchronized,还提供了 Lock 体系。显式锁能提供更灵活的能力,例如尝试获取、超时获取、可中断获取、公平锁和多个条件队列。

# 1. Lock 基本用法

Lock lock = new ReentrantLock();

lock.lock();
try {
    updateState();
} finally {
    lock.unlock();
}

必须在 finally 中释放锁,否则异常会导致锁永远不释放。

# 2. ReentrantLock

ReentrantLock 是可重入锁。

private final ReentrantLock lock = new ReentrantLock();

public void outer() {
    lock.lock();
    try {
        inner();
    } finally {
        lock.unlock();
    }
}

public void inner() {
    lock.lock();
    try {
        // same thread reenter
    } finally {
        lock.unlock();
    }
}

同一线程可以多次获取同一把锁,但也必须释放相同次数。

# 3. tryLock

立即尝试:

if (lock.tryLock()) {
    try {
        doWork();
    } finally {
        lock.unlock();
    }
} else {
    fallback();
}

带超时:

if (lock.tryLock(100, TimeUnit.MILLISECONDS)) {
    try {
        doWork();
    } finally {
        lock.unlock();
    }
}

适合避免无限等待、降低死锁风险。

# 4. lockInterruptibly

lock.lockInterruptibly();
try {
    doWork();
} finally {
    lock.unlock();
}

等待锁期间可以响应中断。适合任务取消、超时控制等场景。

# 5. 公平锁与非公平锁

Lock fairLock = new ReentrantLock(true);
类型 特点
非公平锁 默认,吞吐通常更高,允许插队
公平锁 尽量按等待顺序获取,吞吐可能下降

公平锁减少饥饿,但调度成本更高。默认一般使用非公平锁。

# 6. Condition

Condition 是与 Lock 配套的条件队列。

Lock lock = new ReentrantLock();
Condition notEmpty = lock.newCondition();

lock.lock();
try {
    while (queue.isEmpty()) {
        notEmpty.await();
    }
} finally {
    lock.unlock();
}

唤醒:

lock.lock();
try {
    queue.offer(item);
    notEmpty.signal();
} finally {
    lock.unlock();
}

一把锁可以创建多个 Condition,适合生产者消费者中区分 notEmpty 和 notFull。

# 7. ReadWriteLock

读写锁允许多个读线程并发,写线程互斥。

ReadWriteLock rw = new ReentrantReadWriteLock();
Lock readLock = rw.readLock();
Lock writeLock = rw.writeLock();

适合读多写少:

读 + 读:可并发
读 + 写:互斥
写 + 写:互斥

如果写很多,读写锁优势会降低。

# 8. StampedLock

StampedLock 提供乐观读。

long stamp = lock.tryOptimisticRead();
double currentX = x;
double currentY = y;
if (!lock.validate(stamp)) {
    stamp = lock.readLock();
    try {
        currentX = x;
        currentY = y;
    } finally {
        lock.unlockRead(stamp);
    }
}

适合读非常多、写较少的场景。但 API 更复杂,不可重入,使用要谨慎。

# 9. AQS 简介

很多同步器基于 AQS:AbstractQueuedSynchronizer。

AQS
├─ state:同步状态
└─ CLH 队列:等待线程队列

典型基于 AQS 的类:

  • ReentrantLock
  • Semaphore
  • CountDownLatch
  • ReentrantReadWriteLock

理解 AQS 有助于理解锁竞争和线程等待队列。

# 10. 锁选型

需求 推荐
简单互斥 synchronized
尝试锁/超时锁/可中断锁 ReentrantLock
多条件队列 ReentrantLock + Condition
读多写少 ReadWriteLock
极读多且能接受复杂 API StampedLock
单变量原子更新 Atomic/LongAdder

# 专家实践与边界

锁的本质是保护共享状态的不变量。选择锁之前,先确认是否真的需要共享可变状态;能用不可变、线程封闭、消息队列解决的问题,通常比加锁更好维护。

共享状态
  │
  ▼
不变量:状态必须保持一致
  │
  ▼
临界区:检查 + 修改
  │
  ▼
锁保护完整临界区
锁 适合 注意点
synchronized 简单互斥 语义清晰,JVM 优化成熟
ReentrantLock 需要超时、可中断、公平锁 必须 finally 解锁
ReadWriteLock 读多写少 写锁饥饿和锁升级问题
StampedLock 读多写少且追求性能 不可重入,使用复杂

锁优化不要从“换锁类型”开始,而要先减少锁范围、降低共享、拆分热点、避免锁内 IO,并用线程 dump 和指标确认竞争点。

# Tips 快问快答

Q:Lock 使用最重要注意什么? A:必须在 finally 中 unlock。

Q:ReentrantLock 是可重入的吗? A:是,同一线程可以重复获取。

Q:公平锁一定更好吗? A:不一定,公平锁吞吐通常更低。

Q:tryLock 适合什么? A:避免无限等待,做降级或超时控制。

Q:Condition 比 wait/notify 好在哪里? A:一把锁可以有多个条件队列,唤醒更精准。

Q:读写锁适合什么场景? A:读多写少,读操作耗时较明显。

Q:StampedLock 可重入吗? A:不可重入,使用时要谨慎。

Q:AQS 是什么? A:很多锁和同步器的基础框架,维护同步状态和等待队列。

上次更新: 2026/06/25, 14:19:18
原子操作类Atomic
并发容器

← 原子操作类Atomic 并发容器→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式