面试题——讲一讲乐观锁与悲观锁?

实习生面试,锁方面的知识,其实小公司面试的不是很深入,不过大公司应该会问的比较仔细,遇到便记录下来

1.悲观锁

悲观锁,就是认为在最坏的情况下,每次读取数据的时候,该数据都会被他人修改,所以每次取数据之前,都要加锁。只有拥有该锁的人,才可以对该数据进行操作。其他人要操作该数据的话,必须等到持有锁,才能进行操作。悲观锁适用于“写”操作比较多的情况,在java中,syschronized(重量级锁)和ReentrantLock(重入锁)都是悲观锁,每次只能有一个线程访问。

2.乐观锁

乐观锁,就是认为在最好的情况下,每次取数据的时候,他人都不会更改该数据。乐观锁其实并不是真正的锁,乐观锁是一种无锁机制,没有使用锁,但是可以实现线程间的同步。

乐观锁试用于多“读”的情况。即资源间竞争较少的情况。这样可以提高cpu的吞吐量。

乐观锁的实现方式有两种,即 “版本号机制” 和CAS(compare and swap译为比较并替换)

版本号机制:一般用于数据表,在数据表中添加一个verson字段,每次操作完成,则version的值加1。当A更新数据值的时候,会先读取version的值,然后在更新的时候,把获取到的version值与数据库当前的version值比较,如果相同,则更新完成,代表成功。如果值不相等,则再次重新获取,然后再次比较,直到成功为止。

sql语句案例: update table_A set age=12 and version=version+1 where id=? and version=version

上述sql语句就是版本号机制的应用。

CAS机制:比较并且替换。在每次操作数据的时候,先读取该数据值,然后在执行具体操作的时候,比较读取到的值是否与当前数据库的值相同。相同则把当前数据库的值替换为新值,代表操作成功。如果值不相同,则再次读取数据值,然后再次和当前数据值比较,直到成功为止。

其中涉及到三个值:

1.需要操作的值V

2.当前数据库的值A

3.新值B

从上述两种实现方案来看,其实版本号机制和CAS机制很相近。

缺点:

1.两种方案都会遇到ABA问题:

假设三个线程同时访问一个共享资源A,线程1,3首先读取到A值,然后线程1把A修改成了B,线程2读取到B值,把B修改为A。现在到了线程3,之前读取到的值是A,现在当前数据值也是A,没有发现在此过程中,A变成了B,然后再次变为A。线程3是任务该资源没有发生变成。这就是ABA问题。

2.循环时间过程,会占用大量的cup资源。

如果长时间没成功,代表该线程一直在重复的进行比较操作,会极大成都的占用cup的资源。导致性能降低。

3.乐观锁只能实现一个共享遍历的原子操作,无法实现多个共享变量的原子操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值