欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

乐观锁、悲观锁

程序员文章站 2022-06-02 11:05:18
...


乐观锁对应于生活中乐观的人总是想着事情往好的方向发展;
悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。

1 悲观锁

总是假设最坏的情况,每次去拿数据的时候都认为会被修改,所以每次拿数据的时候都会上锁。这样别人想拿这个数据就会阻塞直到它拿到锁。

共享资源每次只给一个线程使用,其他线程阻塞,用完之后再把资源转让给其他线程。

2 乐观锁

总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁。但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,++可以使用版本号机制CAS算法实现。++


2.1 CAS算法 (Compare and Swap)

是一种无锁算法,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻赛的情况下实现变量的同步,所以也叫非阻赛同步。(Java语言)

CAS算法涉及到三个操作数:需要读写的内存值V、进行比较的值A、待写入的新值B。
当且仅当V == A时,CAS通过原子操作用新值B来更新V值,否则不会执行任何操作。(比较+替换=一个原子操作)

CAS算法的缺点 -- ABA问题

如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那么我们就能说明它的值没有被其他线程修改过吗?
很明显不是,因为在这段时间内它的值可能被改为其他值,然后又被改回A,那CAS操作就会认为它从来没被改过。
这个问题被称为CAS操作的 “ABA” 问题。

2.2 版本号机制 – 可用于解决ABA问题

一般是在数据表中加上一个数据库版本号version字段,表述数据被修改的次数,当数据被修改时version值会加1。

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


3 c++ 中用过哪些锁?c++ 中有乐观锁吗?

c++线程之间的锁有:进程和线程的博客有讲

  • 互斥锁
  • 条件锁
  • 自旋锁
  • 读写锁
  • 递归锁

c++中应该没有乐观锁,java中有,CAS算法就是java中的。