在 Java 中,锁的分类和实现方式多种多样,主要可以分为以下几类:
1. 乐观锁与悲观锁
- 乐观锁:认为数据在并发操作时不会被修改,因此不加锁,只在更新时检查数据是否被修改。常见的实现方式是 CAS(Compare and Swap),如 AtomicInteger、AtomicLong 等原子类。
- 悲观锁:认为数据在并发操作时一定会被修改,因此在操作前加锁。常见的实现方式是 synchronized 关键字和 ReentrantLock。
2. 可重入锁与非可重入锁
- 可重入锁:允许同一个线程多次获取同一把锁,如 synchronized 和 ReentrantLock。
- 非可重入锁:不允许同一个线程多次获取同一把锁,必须等待锁释放后才能再次获取
3. 公平锁与非公平锁
- 公平锁:按照线程申请锁的顺序分配锁,保证先到先得,如 ReentrantLock 的公平模式。
- 非公平锁:不保证申请锁的顺序,可能导致某些线程长时间无法获取锁,但性能较高。
4. 自旋锁与阻塞锁
- 自旋锁:线程在获取锁失败时不会立即阻塞,而是通过循环(自旋)尝试获取锁,适用于锁竞争不激烈的场景。
- 阻塞锁:线程在获取锁失败时会进入阻塞状态,等待锁释放后被唤醒。
5. 互斥锁与读写锁
- 互斥锁:同一时刻只允许一个线程访问共享资源,如 synchronized 和 ReentrantLock。
- 读写锁:允许多个读线程同时访问共享资源,但写线程独占资源,如 ReentrantReadWriteLock。
6. 锁升级
- 偏向锁:适用于只有一个线程访问同步代码块的场景,减少锁的开销。
- 轻量级锁:当偏向锁被其他线程访问时,升级为轻量级锁,通过自旋尝试获取锁。
- 重量级锁:当自旋次数达到一定阈值后,升级为重量级锁,线程进入阻塞状态。
7. 分段锁
- 将锁的粒度细化,对不同的数据段使用不同的锁,减少锁竞争,如 ConcurrentHashMap 的实现。
总结
Java 中的锁可以根据不同的特性进行分类,如乐观锁与悲观锁、可重入锁与非可重入锁、公平锁与非公平锁等。常见的锁实现包括 synchronized、ReentrantLock、ReentrantReadWriteLock 以及原子类(如 AtomicInteger)。选择合适的锁可以提高并发性能并避免死锁等问题。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。