乐观锁常见的两种实现方式和适用场景

1、版本号机制

    一般是在数据表中加上一个版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读到的version值与当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。

 

举一个简单的例子:

假设数据库中账户信息表中有一个version字段,当前值为1;而当前账户余额字段为100;

1、操作员A此时将其读出(version=1),并从其账户余额中扣除50(100-50);

2、在操作员A操作的过程中,操作员B也读入此用户信息(version=1),并从其账户余额中扣除20(100-20);

3、操作员A完成了修改操作,将数据版本号+1(version=2),连同账户扣除后余额(子段=50),提交至数据库更新,此时由于 提交数据库版本大于数据库当前记录的版本,数据被更新,数据库记录version更新为2.

4、操作员B完成了操作,也将版本号+1(version=2)试图向数据库提交数据(子段=80),但此时比对数据库记录版本时发现,操作员B提交的数据版本号为2,数据库记录当前版本也为2,不满足“提交版本必须大于记录当前版本才能执行更新”的乐观锁策略,因此,操作员B的提交被驳回。

这样就避免了操作员B用基于version=1的旧数据修改的结果覆盖操作员A的操作结果的可能。

2、CAS算法

即compare and swap(比较和互换),是一种有名的无锁算法。无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步。CAS算法涉及到3个操作数。

1、需要读写的内存值V

2、进行比较的值A

3、拟写入的新值B

当且仅当V的值等于A时,CAS通过原子方式用新值B来更新V的值,否则不会执行任何操作(比较和替换是一个原子操作)。一般情况下是一个自旋操作,即不断的重试。

 

CAS和synchronized的使用场景

1、对于资源竞争较少(线程冲突较轻)的情况,使用synchronized同步锁进行线程阻塞和唤醒切换以及用户内核态间的切换操作额外浪费消耗cpu资源;而CAS基于硬件实现,不需要进入内核,不需要切换线程,操作自旋几率较少,因此可以获得更高的性能。

2、对于资源竞争严重(线程冲突严重)的情况,CAS自旋的概率会比较大,从而浪费更多的CPU资源,效率低于synchronized。

补充:Java并发编程这个领域中synchronized关键字一直都是元老级的角色,很久之前很多人都会称他为“重量级锁”。但是,在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入了偏向锁和轻量级锁以及其他各种优化之后变得在某些情况下并不是那么重了。

synchronized的底层实现主要依靠lock-Free队列,基本思路是自旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了高吞吐量。在线程冲突较少的情况下,可以获得和CAS类似的性能;而线程冲突严重的情况下性能远高于CAS。

  • 20
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
乐观锁和悲观锁是并发控制中常用的两种策略。 乐观锁实现方式是,当多个事务同时访问同一数据时,假设每个事务都能成功地完成操作,直到提交时才会检查是否有冲突。如果检测到冲突(比如数据已被其他事务修改),则会回滚当前事务并重新尝试。 乐观锁实现通常通过为每一条记录添加版本号或时间戳来实现。当事务读取数据时,会记录下当前版本号或时间戳。在提交时,会检查数据库中的当前版本号或时间戳与事务开始时记录的版本号或时间戳是否一致,如果不一致则说明数据已被其他事务修改过,需要回滚当前事务并重新尝试。 悲观锁的实现方式是,在事务执行期间,对数据进行加锁以阻止其他事务对其进行修改。悲观锁认为在事务执行期间会发生冲突,因此提前对数据进行加锁以避免冲突。 悲观锁的实现通常通过数据库的锁机制来实现,比如对某条记录加上排它锁(Exclusive Lock)或共享锁(Shared Lock)。排它锁会阻止其他事务对该记录进行读取和修改,而共享锁只会阻止其他事务对该记录进行修改,但允许读取。 需要注意的是,乐观锁和悲观锁各有优缺点,适用于不同的并发场景乐观锁适用于读多写少的场景,并发性能较好;而悲观锁适用于写多读少的场景,保证数据的一致性和安全性。在实际应用中,根据具体情况选择合适的并发控制策略是很重要的。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值