锁机制
悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。悲观锁的实现,往往依靠底层提供的锁机制;悲观锁会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。
乐观锁:假设不会发生并发冲突,每次不加锁而是假设没有冲突而去完成某项操作,只在提交操作时检查是否违反数据完整性。如果因为冲突失败就重试,直到成功为止。乐观锁大多是基于数据版本记录机制实现。为数据增加一个版本标识,比如在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。
什么是CAS?CAS算法理解
CAS是一种无锁算法,CAS有三个操作数,内存值V,旧的预期值A,要修改的新值B,当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。CAS比较与交换的伪代码表示:
如t1和t2线程同时操作变量
t1和t2同时去访问变量a,他们会把驻内存的数据完全copy一份到自己的工作内存空间,所以t1和t2的旧的“预期值A”都是1,
假设t1在竞争获取操作权,其他线程都失败,此时t1线程更新变量值为2,然后写回主内存。
此时t2不会挂起,会告知这次竞争失败了,t2可以再次发起尝试
现在对t2来说内存值已经变为2了,与预期值1不一致了,就会操作失败。
CAS算法在JDK的应用
调用了sun.misc.Unsafe库里的CAS算法。通过查看AtomicInteger的源码可以发现,受影响的还有getAndAdd、addAndGet等大部分方法。
CAS开销
CAS是CPU指令级的草,只有一步原子操作,速度非常快。对于资源竞争严重的情况,CAS自旋的概率会比较大,从而浪费更多的CPU资源,效率低于synchronized
总结
领取专属 10元无门槛券
私享最新 技术干货