乐观锁比较乐观,通过预值或者版本号比较,如果不一致性的情况则通过循环控制修改(不断循环查询版本号),当前线程不会被阻塞,是乐观,效率比较高,但是乐观锁比较消耗 cpu 的资源。 乐观锁:获取锁----如果没有获取到锁,当前线程是不会阻塞等待,通过死循环控制。
在我们表结构中,会新增一个字段就是版本字段
version
varchar(255) DEFAULT NULL,
多个线程对同一行数据实现修改操作,提前查询当前最新的 version 版本号码,作为 update 条件查询,如果当前 version 版本号码发生了变化,则查询不到该数据。
表示如果修改数据失败,则不断重试 ,又重新查询最新的版本实现 update。
需要注意控制乐观锁循环的次数,避免 cpu 飙高的问题。
mysql 的 innodb 引擎中存在行锁的概念
基于CAS实现 原理: 变量=====0 0表示没有线程获取该锁; 1表示已经有线程获取到该锁; Cas获取锁: Cas修改变量值=0->1===Cas修改成功的话则表示获取锁成功 Cas释放锁 变量1->0 Cas释放锁成功
公平锁:就是比较公平,根据请求锁的顺序排列,先来请求的就先获取锁,后来获取锁就最后获取到, 采用队列存放 类似于吃饭排队。底层实现就是链表 非公平锁:不是据请求的顺序排列, 通过争抢的方式获取锁。非公平锁效率比公平锁效率要高,Synchronized 是非公平锁 New ReentramtLock()(true)---公平锁 New ReentramtLock()(false)---非公平锁 底层基于 aqs 实现
在同一个线程中锁可以不断传递的,可以直接获取。
独占锁:在多线程中,只允许有一个线程获取到锁,其他线程都会等待。 共享锁:多个线程可以同时持有锁,例如 ReentrantLock 读写锁。读读可以共享、写写互斥、读写互斥、写读互斥。
CAS:没有获取到锁的线程是不会阻塞的,通过循环控制一直不断的获取锁。
CAS: Compare and Swap,翻译成比较并交换。 执行函数 CAS(V,E, N) CAS 有 3 个操作数,内存值 V,旧的预期值 E(V的备份值),要修改的新值 N。当且仅当预期值 E 和内存值 V 相同时,将内存值 V 修改为 N,否则什么都不做。
什么是ABA问题?
In multithreaded computing, the ABA problem occurs during synchronization, when a location is read twice, has the same value for both reads, and "value is the same" is used to indicate "nothing has changed". However, another thread can execute between the two reads and change the value, do other work, then change the value back, thus fooling the first thread into thinking "nothing has changed" even though the second thread did work that violates that assumption.
Cas 主要检查 内存值 V 与旧的预值值=E 是否一致,如果一致的情况下,则修改。 这时候会存在 ABA 的问题: 如果将原来的值 A,改为了 B,B又改为了A发现没有发生变化,实际上已经发生了变化, 所以存在 Aba 问题。 解决办法:通过版本号码,对每个变量更新的版本号码做+1 解决 aba 问题是否大:概念产生冲突,但是不影响结果,换一种方式 通过版本号码方式。