java中如何选择合适的锁呢?

欢喜 Java经验 发布时间:2025-06-09 09:48:09 阅读数:12641 1
下文笔者讲述java并发编程中,锁的选择简介说明,如下所示
  通过本篇文章的学习,你可以彻底掌握不同的场景选择不同的锁
      如下所示

常见锁类型及其特点

锁类型 所属包 是否内置 可中断 可超时 公平性 支持条件变量 适用场景
`synchronized` 关键字 JVM 内置 方法/代码块同步,简单并发控制
`ReentrantLock` `java.util.concurrent.locks` ✅(可配置) 需要灵活控制的同步场景
`ReentrantReadWriteLock` `java.util.concurrent.locks` ✅(可配置) 读多写少的共享资源控制
`StampedLock` `java.util.concurrent.locks` ✅(部分支持) ✅(部分支持) 高性能读多写少场景
`Semaphore` `java.util.concurrent` ✅(可配置) 资源访问控制、限流
`CountDownLatch` `java.util.concurrent` 多线程协作完成任务
`CyclicBarrier` `java.util.concurrent` 多线程协同执行阶段任务

各种场景选择锁的示例说明

场景一:方法或代码块同步(简单并发)

- 推荐锁:`synchronized`
- 优点:
  - 简单易用,JVM 自动加锁解锁。
  - 性能优化好(偏向锁、轻量级锁)
  
-例
public synchronized void doSomething() {
    // 同步方法体
}

场景二:需要尝试获取锁、设置超时、公平锁等高级功能

- 推荐锁:`ReentrantLock`
- 优点:
  - 支持尝试锁 (`tryLock`)、超时、公平锁。
  - 更细粒度控制,适合复杂并发逻辑。
  
- 例:
ReentrantLock lock = new ReentrantLock(true); // 公平锁
lock.lock();
try {
    // 临界区操作
} finally {
    lock.unlock();
}

场景三:读多写少(如缓存、配置管理)

- 推荐锁:`ReentrantReadWriteLock` 或 `StampedLock`
- 区别:
  - `ReentrantReadWriteLock`:适合写频率不高的场景,读锁共享,写锁独占。
  - `StampedLock`:提供乐观读锁,适合高并发读场景,性能更高。
  
- 例(ReentrantReadWriteLock):

ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
rwLock.readLock().lock();
try {
    // 读取数据
} finally {
    rwLock.readLock().unlock();
}

场景四:高性能读多写少 + 乐观锁机制

-推荐锁:`StampedLock`
-优点:
  - 支持乐观读锁(不阻塞写线程)。
  - 性能优于 `ReentrantReadWriteLock`。
- 注意:需手动验证戳记是否有效。

- 例:
StampedLock stampedLock = new StampedLock();
long stamp = stampedLock.tryOptimisticRead();
// 读取数据
if (!stampedLock.validate(stamp)) {
    stamp = stampedLock.readLock();
    try {
        // 重新读取数据
    } finally {
        stampedLock.unlockRead(stamp);
    }
}

场景五:线程协作(如生产者-消费者模型)

- 推荐锁:`ReentrantLock` + `Condition`
- 优点:
  - 支持多个等待队列。
  - 可实现精确唤醒特定线程。
  
- 例:
ReentrantLock lock = new ReentrantLock();
Condition notEmpty = lock.newCondition();

lock.lock();
try {
    while (queue.isEmpty()) {
        notEmpty.await(); // 等待生产
    }
    // 消费数据
} finally {
    lock.unlock();
}

场景六:控制资源访问数量(如连接池、限流)

- 推荐锁:`Semaphore`
- 优点:
  - 控制同时访问的线程数量。
  - 可用于信号量、资源池、限流器。
  
-例:
Semaphore semaphore = new Semaphore(3); // 最多允许 3 个线程同时访问

semaphore.acquire();
try {
    // 访问资源
} finally {
    semaphore.release();
}

场景七:多个线程协同执行任务(如并行计算)

- 推荐锁:`CountDownLatch` 或 `CyclicBarrier`
- 区别:
  - `CountDownLatch`:计数递减到 0 后不可复用。
  - `CyclicBarrier`:可重复使用,所有线程到达屏障后统一继续执行。
  
-例(CountDownLatch):

CountDownLatch latch = new CountDownLatch(3);

for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        //执行任务
        latch.countDown();
    }).start();
}

latch.await(); //主线程等待所有子线程完成
System.out.println("所有任务完成");

各种锁超时、公平、可重入说明

场景 推荐锁 是否支持中断 是否支持超时 是否公平 是否可重入
简单同步 `synchronized`
高级锁控制 `ReentrantLock`
读多写少 `ReentrantReadWriteLock` / `StampedLock`
线程协作 `ReentrantLock` + `Condition`
限流 / 资源池 `Semaphore`
多线程协同 `CountDownLatch` / `CyclicBarrier`
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaJingYan/202506/17494337248490.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者