1、 背景
传统Synchronized锁:悲观,如果没有获取到锁的情况下,会让当前线程变为阻塞的状态,释放CPU执行权,效率非常低。
乐观锁:本质上没有锁,没有死锁现象,而且效率比较高,不会释放CPU执行权,预值比较或 版本号控制。CAS、自旋。
2、原理
CAS的英文全称是CompareAndSet,也就是比较然后修改,涉及到三个值,V、E和N,V是主内存的共享变量值,E是工作内存的副本值,N是修改内存的值。关于内存值的修改,有两种情况:第一种情况是比较V和E的值,如果相等,则对V进行修改;第二种情况是V和E不等,说明有线程已经修改过了,那就重新读取主内存的值,再做判断、修改。
V=内存值(共享变量);E=预期值(工作内存值) ;N=新值(需要修改的共享变量值)
第一种情况:(V未被修改)
第一步:读取内存值V,复制给E
第二步:判断V的值,如果V==E,说明共享变量的V没有被修改
第三步:将V的值改为N
第二种情况:(V被修改)
第一步:读取内存之V,复制给E
第二步:判断V的值,如果V!=E,说明别的线程修改了共享变量的V
第三步:重新读取主内存V的值给E
第四步:修改时再判断V的值是否等于E,如果不等,继续自旋,直至相等再将V的值修改为N。
注意:不可能有两个线程同时修改V的值,因为CAS底层通过指令控制了原子性。
3、应用场景
Java UNSAFE类
原子类 Atomic
4、利用CAS原子类方式实现一个锁
1 public class AtomicTryLock { 2 3 /** 4 * 定义AtomicInteger 修改为1表示该锁已经被使用该 修改为0表示为被使用 5 */ 6 private volatile AtomicInteger atomicInteger = new AtomicInteger(0); 7 private Thread lockCurrentThread; 8 9 /** 10 * 尝试获取锁 11 * 12 * @return 13 */ 14 public boolean tryLock() { 15 boolean result = atomicInteger.compareAndSet(0, 1); 16 if (result) { 17 lockCurrentThread = Thread.currentThread(); 18 } 19 return result; 20 } 21 22 /** 23 * 释放锁 24 * 25 * @return 26 */ 27 public boolean unLock() { 28 if (lockCurrentThread != null && lockCurrentThread != Thread.currentThread()) { 29 return false; 30 } 31 return atomicInteger.compareAndSet(1, 0); 32 } 33 34 public static void main(String[] args) { 35 AtomicTryLock atomicTryLock = new AtomicTryLock(); 36 IntStream.range(1, 10).forEach((i) -> new Thread(() -> { 37 38 try { 39 boolean result = atomicTryLock.tryLock(); 40 if (result) { 41 System.out.println(Thread.currentThread().getName() + ",获取锁成功~"); 42 } else { 43 System.out.println(Thread.currentThread().getName() + ",获取锁失败~"); 44 } 45 } catch (Exception e) { 46 e.printStackTrace(); 47 atomicTryLock.unLock(); 48 } finally { 49 atomicTryLock.unLock(); 50 } 51 52 }).start()); 53 } 54 }
5、如何解决CAS产生的ABA问题
5.1 什么是ABA问题
如果【线程1】将原来的值A,改为了B,【线程2】将B又改为了A 发现没有发生变化,实际上已经发生了变化,但是【线程3】修改时判断V值没有发生变化,这种现象为ABA。
5.2 解决办法
通过版本号码,对每个变量更新的版本号码做+1
来源:蚂蚁课堂(mayikt.com)
标签:无锁,return,Thread,CAS,修改,线程,内存,机制 From: https://www.cnblogs.com/pinp/p/16860926.html