CPU|java面试——常见的锁和锁升级


CPU|java面试——常见的锁和锁升级
文章图片
CPU|java面试——常见的锁和锁升级
文章图片
CPU|java面试——常见的锁和锁升级
文章图片
CPU|java面试——常见的锁和锁升级
文章图片
CPU|java面试——常见的锁和锁升级
文章图片
CPU|java面试——常见的锁和锁升级
文章图片
CPU|java面试——常见的锁和锁升级
文章图片
CPU|java面试——常见的锁和锁升级
文章图片
CPU|java面试——常见的锁和锁升级

 经典面试题回顾
宏观上来说锁分类乐观锁乐观锁是一种乐观思想 , 即认为读多写少 , 遇到并发写的可能性低 , 每次去拿数据的时候都认为别人不会修改 , 所以不会上锁 , 但是在更新的时候会判断一下在此期间别人有没有去更新这个数据 , 采取在写时先读出当前版本号 , 然后加锁操作(比较跟上一次的版本号 , 如果一样则更新) , 如果失败则要重复读-比较-写的操作 。
java中的乐观锁基本都是通过CAS操作实现的 , CAS是一种更新的原子操作 , 比较当前值跟传入值是否一样 , 一样则更新 , 否则失败 。
悲观锁悲观锁是就是悲观思想 , 即认为写多 , 遇到并发写的可能性高 , 每次去拿数据的时候都认为别人会修改 , 所以每次在读写数据的时候都会上锁 , 这样别人想读写这个数据就会block直到拿到锁 。 java中的悲观锁就是SynchronizedAQS框架下的锁则是先尝试cas乐观锁去获取锁 , 获取不到 , 才会转换为悲观锁 , 如RetreenLock 。
基础原理回顾

CAS 原理

简单看下jdk中一个cas原理的运用 :  unsafe.class
public final int getAndAddInt(Object var1 long var2 int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1 var2);
 while(!this.compareAndSwapInt(var1 var2 var5 var5 + var4));

return var5;

compareAndSwapInt就是cas 比较和交换
面试回答cas:
什么是CAS:CAS:compare and swap 多线程访问 , 在没有加锁的情况下 , 保证线程一致性的去改变某个值 , 比如有个变量初始值0 , 第一个线程读取过来 , 想加1 , 在把1往回写的时候需要先去读最新的值 , 看看还是不是0 , 如果是 , 则把值改成1 , 如果原来的值已经被别的线程动了 , 改成2了 , 那么此时cas失败 , 值还是2 。 此时第一个线程虽然cas失败了 , 但是并不会被挂起 , 而是自旋 , 他会把最新的2读取 , 然后+1 , 再把3写回去的时候依然去判断原来的值是否被别的线程改变 , 如果改变了继续重复上述步骤 。