锁:乐观锁、悲观锁、自旋锁、

6 篇文章 0 订阅
5 篇文章 0 订阅

目录

乐观锁

version

CAS

使用场景

悲观锁

使用场景


乐观锁

每次获取数据的时候都认为别人不会修改,所以不会上锁。但是在更新的时候会判断在此器间别人是否有更新该数据。如果数据有被修改,则不进行更新;如果没有被修改则进行更新。

一般使用version和CAS方式。

version

一般在数据库表中加上一个版本号version字段,表示数据被修改的次数,当数据被修改时,version加1.

当线程A要更新数据时,在读取数据的同时获取version值,在提交更新时,若刚才读取到的version值与当前数据库中的version相等才会执行更新,否则重试更新操作,直到成功。

CAS

即compare and swap或者compare and set。涉及到数据所在的内存值、预期值、新值。当需要更新时判断当前内存值与读取到的是否相等,若相等则用新值更新,若失败则重试,一般情况下是自旋操作,即不断的重试。

可以用for于CAS联用实现简易自旋锁。

for {
 if atomic.CompareAndSwapInt32(&num2, 10, 0) {
  fmt.Println("The second number has gone to zero.")
  break
 }
 time.Sleep(time.Millisecond * 500)
}

使用场景

适合读取比较频繁的场景,如果出现大量的写入则数据可能会出现冲突。为了保证数据一致性,应用层则需要不断的重新获取数据,这样会增大查询操作,降低了吞吐量。

悲观锁

每次获取数据都担心数据被修改,所以每次获取数据都会加锁,确保在使用过程中数据不会被修改,使用完后解锁。

使用场景

适合写入操作频繁的场景。如果大量的读操作,每次读取的时候都加锁增大了开销,降低了吞吐量。

自旋锁

使线程在没有取得锁的情况下不被挂起,转去执行空循环(自己执行空循环),若在若干个空循回后,线程如果可以获得锁,则继续执行,若依然不能获得锁才被挂起。

可能引发的问题

1.过多占据CPU时间:如果锁的当前持有者长时间不释放该锁,那么等待者将长时间占据CPU,导致CPU浪费,因此可以设定一个时间,当锁的持有者超过这个时间不释放锁时,等待者就放弃cpu时间片。

2.死锁问题:有一个线程连续两次试图获得自旋锁,第一次这个线程获得了该锁,当第二次试图加锁时检测到锁已被占用(其实被自己占用),那么这时线程会一直等待自己释放该苏哦,而不能继续执行,这样就引起了死锁。

因此递归程序不能在持有自旋锁的时候调用自己

阻塞锁

让线程进入阻塞状态进行等待,当获得相应的信号(唤醒、时间)时才可以进入线程的准备就绪状态,准备就绪状态的所有线程通过竞争进入运行态。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值