乐观锁、悲观锁
程序员文章站
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中的。
下一篇: php 生成验证码代码