讲一讲悲观锁和乐观锁?
讲一讲悲观锁和乐观锁?
程序员朱永胜有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准
https://blog.zysicyj.top
全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java 面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。https://store.amazingmemo.com/chapterDetail/1685324709017001`
悲观锁(Pessimistic Locking)
悲观锁 基于这样一个假设:在多线程的环境下,冲突发生的概率比较高,因此在读取或者写入数据的时候应该先将数据锁定,避免其他线程对数据进行修改,造成数据的不一致。
在 Java 中,悲观锁 可以通过多种方式实现,比如:
- Synchronized 关键字:这是 Java 语言内置的同步机制,它可以用于方法级别或者代码块级别。
- Lock 接口:在
java.util.concurrent.locks
包中的ReentrantLock
类就是一个显式的锁,比较灵活,支持公平锁和非公平锁。
悲观锁的特点是保持数据的严格一致性,但是可能会降低并发效率,因为在等待锁的过程中,其他所有需要访问该数据的线程都会被阻塞。
乐观锁(Optimistic Locking)
与悲观锁不同,乐观锁 是基于这样的假设:多线程并发访问不会总是发生修改,因此不需要通过锁机制来保证数据的一致性,而是采用一种 “ 先做后检查 “ 的方式。
乐观锁通常的实现方式是 版本号机制 或CAS 算法(Compare And Swap/Set)。
- 版本号机制:每次读取数据时,会同时获取一个版本号,并在更新数据时检查这个版本号是否发生变化。如果没有变化,则执行更新;如果已经变化,则说明数据在读取后已经被其他线程修改过,此时可以选择放弃更新或者重试。
- CAS 算法:Java 的
java.util.concurrent.atomic
包下面的原子类就是采用 CAS 算法实现的。这种方法会在数据更新时进行比较并交换,确保数据的一致性。
乐观锁适用于冲突较少的情况,可以提高系统的并发能力。但在冲突较多时,如果大量重试,可能会导致性能下降。