1分钟快速了解——Java几种常见的锁

  • 乐观锁
  • 悲观锁
  • 公平锁
  • 非公平锁
  • 可重入锁
  • 独占锁(写锁)
  • 共享锁(写锁)

乐观锁(自旋锁):认为共享资源每次被访问都不会出现安全问题,无需加锁。

CAS算法和版本号法就是乐观锁的具体实现。

CAS只有当旧值和预期值一样,再将旧值更新为新值。但是CAS存在ABA问题,即对数据进行修改,随后又复原为原值的问题。解决这一问题可以使用版本号法。

悲观锁:认为共享资源每次被访问时都会出现安全问题,故每次获取资源都需要上锁。

synchronizedReentrantLock等独占锁都是悲观锁。

公平锁:锁被释放后,先申请的线程先获得锁。性能比较差,因为CPU唤醒线程具有一定的开销。

非公平锁:锁被释放后,后申请的线程可能先后去锁,是随机的或者按照优先级排序的。性能更好,因为减少了CPU唤醒线程的开销。但是也可能导致饥饿现象(某些线程永远获取不到锁)。

ReentrantLock默认创建的是非公平锁,可以通过其构造器传参创建公平锁和非公平锁。
true:公平锁
false:非公平锁

可重入锁:一个线程可以多次获取同一个锁。如一个线程获得了一个锁,这时锁还没有释放,而线程想要再次获取锁是可以的,如果是不可重入锁,就会导致死锁。

synchronizedReentrantLock都是可重入锁。

独占锁(写锁):最多只能同时被一个线程获取。

共享锁(读锁):可以同时被多个线程获取。

synchronized和ReentrantLock的区别

区别synchronizedReentrantLock
加锁、解锁自动手动,配合try、finally语句块实现
中断等待锁的线程不可中断能够中断
超时等待不支持支持
支持公平/非公平锁非公平锁构造方法工作两种锁

synchronized的锁升级

过程:偏向锁—>轻量级锁—>重量级锁

偏向锁:jdk8默认是轻量级锁,但如果设定了 -XX:BiasedLockingStartupDelay = 0 ,则会获得一把偏向锁,并且锁对象的markword会记录偏向锁线程ID。

轻量级锁:当下一个线程竞争偏向锁时,会判断markword中的偏向锁ID是否为当前线程,如果不相等,偏向锁就会升级会轻量级锁。每个线程再通过CAS自旋的操作获取锁。

重量级锁:如果锁竞争加剧(线程自旋次数获自旋线程数超过某个阈值),轻量级锁升级为重量级锁。申请资源的线程会被挂起,进入到操作系统内核态的等待队列中,等待操作系统调度,然后映射回用户态。

在这里插入图片描述

Java 中的“”是用于控制多个线程对共享资源并发访问的同步机制。根据使用场景和实现方式的不同,Java 提供了多种类型的,主要可以分为以下几类: --- ### ✅ 一、按语言层级分类 | 类型 | 说明 | |------|------| | **synchronized 关键字** | JVM 内置的隐式(也叫监视器 Monitor Lock),最基础的同步机制 | | **ReentrantLock** | `java.util.concurrent.locks.Lock` 接口的实现,显式,功能更强大 | | **其他显式** | 如 `ReadWriteLock`、`StampedLock` 等 | --- ## 🔐 Java 主要类型详解 ### 1. **synchronized (内置 / Monitor )** - 自动获取与释放,无需手动控制 - 可修饰:方法、代码块 - 原理:每个对象都有一个 monitor(监视器),线程进入 synchronized 区域前必须获得该 monitor ```java // 同步方法 public synchronized void method() { ... } // 同步代码块 synchronized(this) { // 临界区 } ``` ✅ 特点: - 重入性(可重入) - 非公平(但JVM优化后可能有偏向) - 不支持超时、中断等高级操作 --- ### 2. **ReentrantLock(可重入)** - 显式,需手动加/解 - 实现了 `Lock` 接口 - 支持公平和非公平(默认是非公平) ```java private final ReentrantLock lock = new ReentrantLock(); public void method() { lock.lock(); // 手动加 try { // 临界区 } finally { lock.unlock(); // 必须在finally中释放 } } ``` ✅ 优势: - 支持公平 - 支持尝试获取(`tryLock()`) - 支持中断等待(`lockInterruptibly()`) - 支持超时(`tryLock(timeout, unit)`) --- ### 3. **ReentrantReadWriteLock(读写)** - 分为读和写 - 多个线程可同时持有读(读读不互斥) - 写是独占的(写时不能读也不能写) ```java private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); private final Lock readLock = rwLock.readLock(); private final Lock writeLock = rwLock.writeLock(); public void read() { readLock.lock(); try { // 读操作 } finally { readLock.unlock(); } } public void write() { writeLock.lock(); try { // 写操作 } finally { writeLock.unlock(); } } ``` 📌 适用场景:读多写少(如缓存) --- ### 4. **StampedLock(JDK 8 引入)** - 更高性能的读写变体 - 使用“戳记(stamp)”机制避免一些冲突 - 支持三种模式: - **写(writeLock)** - **悲观读(readLock)** - **乐观读(optimisticRead)** ```java private final StampedLock stampedLock = new StampedLock(); // 乐观读示例 long stamp = stampedLock.tryOptimisticRead(); if (!dataValid()) { // 升级为悲观读 stamp = stampedLock.readLock(); } try { // 使用数据 } finally { if (StampedLock.isWriteLockStamp(stamp)) { stampedLock.unlock(stamp); } } ``` ⚠️ 注意:乐观读不能直接调用 unlock,需要判断是否升级。 --- ### 5. **Condition(条件变量)配合 Lock 使用** - 类似于 `Object.wait()` / `notify()`,但更灵活 - 每个 `Lock` 可创建多个 `Condition`,实现精确唤醒 ```java private final ReentrantLock lock = new ReentrantLock(); private final Condition notFull = lock.newCondition(); private final Condition notEmpty = lock.newCondition(); ``` 📌 常用于生产者-消费者模型。 --- ### 6. **其他特殊用途** | 类型 | 说明 | |--------|------| | **Semaphore(信号量)** | 控制同时访问资源的线程数量(限流),不是传统意义上的“” | | **CountDownLatch** | 等待一组操作完成后再继续,用于协调线程 | | **CyclicBarrier** | 多个线程互相等待到达某个点再一起继续 | | **Phaser** | 更灵活的同步屏障(JDK 7+) | > ❗ 这些不属于“互斥”,而是**同步辅助工具**,但常被归类讨论。 --- ### ✅ 按特性分类总结 | 类型 | 是否可重入 | 是否公平 | 是否显式 | 适用场景 | |--------|------------|----------|-----------|------------| | `synchronized` | ✅ 是 | ❌ 否(偏斜优化) | ❌ 隐式 | 简单同步 | | `ReentrantLock` | ✅ 是 | ✅ 可设置 | ✅ 显式 | 高级控制需求 | | `ReentrantReadWriteLock` | ✅ 是 | ✅ 可设置 | ✅ 显式 | 读多写少 | | `StampedLock` | ✅ 是 | ❌ 否 | ✅ 显式 | 高性能读写场景 | | `Semaphore` | ❌ 否 | ✅ 可设置 | ✅ 显式 | 资源池/限流 | --- ### ✅ 总结:Java常见的“”有哪些? 1. **synchronized** —— 内置,简单高效 2. **ReentrantLock** —— 显式可重入,功能丰富 3. **ReentrantReadWriteLock** —— 读写分离 4. **StampedLock** —— 高性能读写(推荐替代读写) 5. **Condition** —— 条件变量,配合 Lock 实现复杂协作 6. **Semaphore / CountDownLatch / CyclicBarrier** —— 同步工具(非互斥) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值