java 中的乐观锁和悲观锁?
java 中的乐观锁和悲观锁?
程序员朱永胜有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准
https://blog.zysicyj.top
全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java 面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。https://store.amazingmemo.com/chapterDetail/1685324709017001`
Java 中的乐观锁和悲观锁
在并发编程中,锁是用来控制多个线程访问共享资源的一种机制。在 Java 中,乐观锁和悲观锁是两种常见的锁机制,它们用于处理不同的并发冲突。
悲观锁(Pessimistic Locking)
悲观锁 假设最坏的情况,即在任何时候都认为其他线程会尝试修改共享数据。因此,它会在数据被处理之前先加锁,确保其他线程无法访问该数据。这种锁的特点是在整个数据处理过程中持有锁,直到事务完成。
特点
- 阻塞性:当一个线程持有锁时,其他所有需要该锁的线程都会被阻塞。
- 数据安全:由于在整个数据处理过程中都持有锁,因此可以保证数据的安全性。
- 可能导致死锁:如果不同的线程以不同的顺序请求锁,可能会导致死锁。
示例
在 Java 中,悲观锁可以通过 synchronized
关键字或者 ReentrantLock
类实现。
1 | public class PessimisticLockExample { |
乐观锁(Optimistic Locking)
乐观锁 则是一种更加宽松的锁机制,它假设多数情况下不会发生修改冲突。乐观锁通常不会直接阻止其他线程对数据的访问,而是在数据提交更新时检查是否有冲突发生。
特点
- 非阻塞性:线程不会因为尝试访问数据而被阻塞。
- 版本控制:通常通过数据版本号(如数据库中的时间戳或版本字段)来实现。
- 冲突解决:如果检测到冲突,可以重试操作或者回滚。
示例
在数据库中,乐观锁通常通过在表中添加一个版本号字段来实现。在更新记录时,会检查版本号是否发生变化。
1 | UPDATE table_name SET column1 = value1, version = version + 1 WHERE id = some_id AND version = current_version; |
在 Java 代码中,可以使用 AtomicInteger
或 AtomicReference
等原子类来实现乐观锁。
1 | public class OptimisticLockExample { |
总结
悲观锁和乐观锁是处理并发问题的两种不同策略。悲观锁适用于写操作多的场景,可以避免数据不一致的问题,但可能会降低系统的吞吐量。乐观锁适用于读操作多的场景,系统吞吐量较高,但需要处理冲突的可能性。在实际应用中,选择合适的锁策略对于提高系统性能和可靠性至关重要。