一、锁是什么
锁是一种用于控制多个线程对共享资源访问的同步机制。它的主要作用是确保同一时刻只有一个线程可以访问共享资源,从而避免数据竞争和不一致性问题
锁的核心特性包括:
- 互斥性:同一时刻只有一个线程可以持有锁
- 可见性:锁的释放和获取操作会强制刷新线程的工作内存,确保共享变量的可见性
- 可重入性:同一个线程可以多次获取同一把锁
二、多线程中的锁分类
多线程中的锁可以根据不同的标准进行分类
1、按锁的实现方法
1、内置锁(synchronized)
-
Java提供的关键字,基于JVM实现
-
使用简单,但功能有限
public synchronized void method() { // 同步代码 }
2、显式锁(ReentrantLock)
-
java.util.concurrent.locks包下的锁实现
-
功能更强大,支持公平锁、可中断锁、超时获取锁等
Lock lock = new ReentrantLock(); lock.lock(); try { // 同步代码 } finally { lock.unlock(); }
2、按锁的特性
1、可重入锁
- 同一个线程可以多次获取同一把锁
- 例如:synchronized和ReentrantLock
2、不可重入锁
- 同一个线程只能获取一次锁
- 例如:NonReentrantlock(需要自定义实现)
3、公平锁
- 按照线程请求锁的顺序分配锁
- 例如:ReentrantLock(true)
4、非公平锁
- 不保证线程获取锁的顺序
- 例如:synchronized和ReentrantLock(false)
3、按锁的粒度
1、粗粒度锁
- 锁的粒度较大,保护整个资源或方法
- 例如:synchronized修饰整个方法
2、细粒度锁
- 锁的粒度较小,保护部分资源或代码块
- 例如:synchronized修饰代码块,或适用多个ReentrantLock
4、按锁的状态
1、乐观锁
- 假设没有冲突,直接操作数据,如果发现冲突则重试
- 例如:CAS操作、Atomic类
2、悲观锁
- 假设会发生冲突,先加锁再操作数据
- 例如:synchronized和ReentrantLock
5、按锁的功能
1、读写锁(ReentrantReadWriteLock)
-
支持读锁和写锁分离,读操作可以并发,写操作互斥
ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); Lock readLock = lock.readLock(); Lock writeLock = lock.writeLock();
2、条件变量(Condition)
-
用于线程间的协作,类似于wait()和notify()
Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); condition.await(); // 等待 condition.signal(); // 唤醒
3、自旋锁
- 线程在获取锁失败时,不会阻塞,而是循环尝试获取锁
- 适用于锁竞争不激烈的场景
4、分布式锁
- 用于分布式系统中,确保多个节点之间的同步
- 例如:基于Redis或ZooKeeper实现的分布式锁
三、常见锁的实现
1、synchronized
- 内置锁,基于JVM实现
- 支持可重入性,但不支持公平锁、可中断锁等功能
2、ReentrantLock
- 显示锁,基于AQS(AbstractQueuedSynchronizer)实现
- 支持公平锁、可中断锁、超时获取锁等功能
3、ReentrantReadWriteLock
- 读写锁,支持读锁和写锁分离
- 读锁是共享锁,写锁是独占锁
4、StampedLock
- Java8引入的锁,支持乐观读锁、悲观读锁和写锁
- 性能优于ReentrantReadWriteLock
5、Atomic类
- 基于CAS实现的无锁操作
- 适用于简单的原子操作
四、锁的应用场景
1、synchronized
- 适用于简单的同步场景,例如保护共享变量或方法
2、ReentrantLock
- 适用于复杂的同步场景,例如需要公平锁、可中断锁或超时获取锁
3、ReentrantReadWriteLock
- 适用于读多写少的场景,例如缓存系统
4、StampedLock
- 适用于高并发读场景,例如统计系统
5、Atomic类
- 适用于低竞争场景,例如计数器
五、锁的优缺点
优点
- 保证线程安全:避免数据竞争和不一致性问题。
- 支持复杂同步逻辑:例如条件变量、读写锁等。
缺点
- 性能开销:锁的获取和释放会带来性能开销。
- 死锁风险:如果锁的使用不当,可能导致死锁。
- 复杂性:显式锁需要手动管理锁的获取和释放。

1557

被折叠的 条评论
为什么被折叠?



