悲观锁和乐观锁是两种处理并发访问的不同策略,它们关注的是在多个线程同时访问共享资源时如何保证数据一致性的问题。
1、悲观锁:
- 定义: 悲观锁的基本思想是,在整个数据处理过程中,将共享资源进行加锁,以防止其他线程的干扰。
- 实现:
通常通过数据库的行锁或者Java中的synchronized关键字来实现。在悲观锁的情境下,线程认为在执行期间其他线程可能会修改共享资源,因此在访问共享资源之前,先获取锁,确保自己是独占资源的。例如 Collections.synchronizedMap 多线程Map用到的就是悲观锁。
2、乐观锁:
- 定义:
乐观锁的基本思想是,在整个数据处理过程中,不对共享资源进行加锁,而是在访问时假设其他线程不会修改共享资源,只有在真正更新时才检查是否有冲突。 - 实现: 通常通过版本号(版本控制)或者CAS(Compare and Swap)等机制来实现。在乐观锁的情境下,线程在读取共享资源时不会加锁,而是在更新时检查是否有其他线程修改过,如果有,则进行相应处理。
悲观锁: 就好比一个人在使用自动取款机(ATM)时,先取号排队,然后在自己的操作过程中,不让其他人插队或者干扰,确保自己独享ATM资源。
乐观锁:
就好比一个人在自动取款机前,直接去尝试取款,但在取款的时候,会检查自己的操作是否被其他人打扰,如果没有被打扰,就顺利完成取款;如果有冲突,就需要重新尝试或者采取其他措施。
总的来说,悲观锁更加悲观地认为会有冲突,因此提前加锁以保护资源;而乐观锁更加乐观地认为冲突不会经常发生,因此先尝试操作,再在需要的时候进行冲突检测和处理。