1. 偏向锁 → 轻量级锁 → 重量级锁
Java 中的 synchronized
锁有三种状态:偏向锁 → 轻量级锁 → 重量级锁,这些锁通过对象头中的 mark word
来标明锁的状态
偏向锁
- 定义:当锁没有竞争时,无需加锁,只需打个标记
- 工作原理:
- 对象初始化后,若没有线程访问该对象的锁,则该对象是可偏向的
- 当第一个线程访问并尝试获取锁时,锁会记录该线程作为锁的拥有者
- 后续线程尝试获取锁时,如果是偏向锁的拥有者,可以直接获得锁,避免执行 CAS 操作
- 性能:性能最佳,适用于无竞争的情况,开销非常小
轻量级锁
- 定义:在大多数情况下,
synchronized
中的代码是由多个线程交替执行的,且通常没有实际的竞争,或者仅存在短时间的竞争,这时使用 CAS 操作可以解决 - 工作原理:
- 当原本是偏向锁的锁被另一个线程访问时,说明出现了竞争,偏向锁将升级为轻量级锁
- 线程会通过自旋的方式尝试获取锁,而不是立即进入阻塞状态
- 性能:性能中等,利用自旋和 CAS 避免了重量级锁带来的线程阻塞和唤醒
重量级锁
- 定义:重量级锁是互斥锁,通过操作系统的同步机制实现,因此其开销较大
- 工作原理:
- 当多个线程发生长期的实际竞争时,轻量级锁无法满足需求,锁会膨胀为重量级锁
- 重量级锁会导致获取不到锁的线程进入阻塞状态
- 性能:性能最差,因为会将线程阻塞,造成较大的开销
锁的升级路径
无锁 → 偏向锁 → 轻量级锁 → 重量级锁
2. 可重入锁 vs 非可重入锁
可重入锁
- 定义:当前线程已经持有该锁时,可以在不释放该锁的情况下,再次获取该锁
- 特点:
- 允许线程在已持有锁的情况下多次获取该锁,不会导致死锁
-
典型实现:synchronized、
ReentrantLock
非可重入锁
- 定义:线程不能在持有该锁的情况下再次获取该锁。若当前线程已经持有该锁,它必须先释放锁,然后才能重新获取该锁
- 特点:
- 线程不能重复获取同一把锁
- 如果当前线程已经持有该锁,再次尝试获取时会导致死锁
3. 共享锁 vs 独占锁
共享锁
- 定义:同一把锁可以被多个线程同时获得
- 特点:
- 多个线程可以同时持有该锁
- 适用于读操作的场景
独占锁
- 定义:锁只能同时被一个线程获得
- 特点:
- 只有一个线程可以持有该锁,其他线程必须等待释放
- 适用于写操作的场景
读写锁中的应用
- 读锁:是共享锁,多个线程可以同时持有该锁
- 写锁:是独占锁,最多只能有一个线程持有该锁,其他线程必须等待
4. 公平锁 vs 非公平锁
公平锁
- 定义:如果线程现在拿不到这把锁,它会进入等待队列,按照排队的顺序等待锁的分配
- 特点:
- 线程会按照先来先得的原则获得锁
- 排队时间较长的线程优先获取锁,确保公平性
非公平锁
- 定义:在某些情况下,忽略排队中的线程,发生插队现象
- 特点:
- 线程不严格按照排队顺序获取锁,可能会发生插队
- 线程在某些情况下会跳过等待队列直接尝试获取锁
5. 悲观锁 vs 乐观锁
悲观锁
- 定义:在获取资源之前,必须先拿到锁,以确保进入“独占”状态
- 特点:
- 当前线程在操作资源时,其他线程无法获取锁,因此其他线程无法干扰当前线程
- 强调对共享资源的保护,适用于资源竞争较为激烈的场景
乐观锁
- 定义:不要求在获取资源前拿到锁,也不锁住资源,而是通过 CAS 理念进行操作
- 特点:
- 在不独占资源的情况下,乐观地进行资源修改
- 假设不会有线程干扰,因此避免了锁的开销,适用于资源竞争较少的场景
6. 自旋锁 vs 阻塞锁
自旋锁
- 定义:当线程无法获取锁时,不会立即进入阻塞状态或释放 CPU 资源,而是通过循环不断尝试获取锁
- 特点:
- 使用循环尝试获取锁,直到成功为止
- 在锁竞争较轻的情况下,能够减少阻塞带来的性能开销
- 适用于锁被短时间占用的场景
阻塞锁
- 定义:当线程无法获取锁时,会直接进入阻塞状态,释放 CPU 资源,等待锁被释放后再重新尝试获取
- 特点:
- 线程一旦无法获得锁,即进入阻塞状态,无法继续执行
- 适用于锁竞争较为激烈的情况,但可能带来较大的上下文切换开销
7. 可中断锁 vs 不可中断锁
可中断锁
- 定义:线程在尝试获取锁的过程中,如果被中断,可以在中断后进行其他操作,而不是一直等待锁
- 特点:
- ReentrantLock 是典型的可中断锁
- 通过
lockInterruptibly
方法,在获取锁的过程中可以响应中断,线程可以在中断后执行其他逻辑,而不必一直等待
不可中断锁
- 定义:一旦线程申请了锁,就没有回头路,必须等待锁被释放,无法响应中断
- 特点:
- 使用
synchronized
关键字修饰的锁是不可中断锁 - 线程在等待锁时,如果被中断,只能等待锁获取完毕后再进行其他操作
- 使用
这是我整理的笔记,目前还在学习阶段,文章中可能有错误和不足,欢迎大家斧正!