CAS 与乐观锁

之前学习并发的东西,了解了一点无锁并发的东西,感觉很神奇。JDK的一些无锁的并发容器是基于CAS做的(如:ConcurrentHashMap),在wiki上看了CAS 的思想,即:比较和交换。最近工作里面要处理一些数据库并发的东西,师兄又和我讲了一下乐观锁的思想和实现,大概意思是每次更新前做对数据库的行记录做一次版本比较,版本相同则进行更新,否则说明这条记录被其他线程修改过了,那么就不进行修改。猛然发现 CAS和乐观锁 思想基本一致(比较当前值跟传入值是否一样,一样则更新,否则失败)。查了些资料,发现CAS是乐观锁的一种实现方式。

那么是否乐观锁就一定比传统的互斥锁强呢?其实并不是的,若发生大量的线程对一个数据库行进行写操作,那么会有大量的写冲突失败操作,系统的性能消耗更大,并发量也没有提高,反而不如使用传统的互斥锁,并发量差不多的情况下,系统的消耗会少的多,因为互斥锁只是阻塞,不会发生乐观锁那样,会多次尝试查询版本号并尝试更新数据。

通过上面的分析,乐观锁的适用场景于就是读多写少的场景。所以根据实际的业务环境选择适合的锁是十分重要的。

下面是摘自《阿里云-java编码规范》

并发修改同一记录时,避免更新丢失,需要加锁。要么在应用层加锁,要么在缓存加
锁,要么在数据库层使用乐观锁,使用 version 作为更新依据。
说明:如果每次访问冲突概率小于 20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次
数不得小于 3

猜你喜欢

转载自blog.csdn.net/qq_24489717/article/details/78556172