1、 背景

  传统Synchronized锁:悲观,如果没有获取到锁的情况下,会让当前线程变为阻塞的状态,释放CPU执行权,效率非常低。

  乐观锁(自旋):本质上没有锁,没有死锁现象,而且效率比较高,不会释放CPU执行权,自旋并通过预值比较或版本号控制。

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)

CAS无锁机制的更多相关文章

  1. CAS无锁机制原理

    原子类 java.util.concurrent.atomic包:原子类的小工具包,支持在单个变量上解除锁的线程安全编程 原子变量类相当于一种泛化的 volatile 变量,能够支持原子的和有条件的读 ...

  2. 二、多线程基础-乐观锁_悲观锁_重入锁_读写锁_CAS无锁机制_自旋锁

    1.10乐观锁_悲观锁_重入锁_读写锁_CAS无锁机制_自旋锁1)乐观锁:就像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态,乐观锁认为竞争不总是会发生,因此它不需要持有锁,将 比较-设置 ...

  3. Atitit。Cas机制 软件开发 编程语言 无锁机制 java c# php

    Atitit.Cas机制 软件开发 编程语言 无锁机制 java c# php 1. 为什么需要无锁操作1 2. 硬件支持 cas  atomic2 3. 无锁编程(Lock-Free)就是在某些应用 ...

  4. (转载)java高并发:CAS无锁原理及广泛应用

    java高并发:CAS无锁原理及广泛应用   版权声明:本文为博主原创文章,未经博主允许不得转载,转载请注明出处. 博主博客地址是 http://blog.csdn.net/liubenlong007 ...

  5. CAS无锁算法与ConcurrentLinkedQueue

    CAS:Compare and Swap 比较并交换 java.util.concurrent包完全建立在CAS之上的,没有CAS就没有并发包.并发包借助了CAS无锁算法实现了区别于synchroni ...

  6. java并发:AtomicInteger 以及CAS无锁算法【转载】

    1 AtomicInteger解析 众所周知,在多线程并发的情况下,对于成员变量,可能是线程不安全的: 一个很简单的例子,假设我存在两个线程,让一个整数自增1000次,那么最终的值应该是1000:但是 ...

  7. CAS 无锁式同步机制

    计算机系统中,CPU 和内存之间是通过总线进行通信的,当某个线程占有 CPU 执行指令的时候,会尽可能的将一些需要从内存中访问的变量缓存在自己的高速缓存区中,而修改也不会立即映射到内存. 而此时,其他 ...

  8. 无锁机制----比较交换CAS Compare And Swap

    一.锁与共享变量 加锁是一种悲观的策略,它总是认为每次访问共享资源的时候,总会发生冲突,所以宁愿牺牲性能(时间)来保证数据安全. 无锁是一种乐观的策略,它假设线程访问共享资源不会发生冲突,所以不需要加 ...

  9. CAS无锁技术

    前言:关于同步,很多人都知道synchronized,Reentrantlock等加锁技术,这种方式也很好理解,是在线程访问的临界区资源上建立一个阻塞机制,需要线程等待 其它线程释放了锁,它才能运行. ...

  10. CAS无锁实现原理以及ABA问题

    CAS(比较与交换,Compare and swap) 是一种有名的无锁算法.无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(N ...

随机推荐

  1. Java注解及应用原理

    视频地址:https://www.bilibili.com/video/BV1Py4y1Y77P/?spm_id_from=333.337.search-card.all.click&vd_s ...

  2. 常见的hash数据结构

    遍历 hash表是一种比较简单和直观的数据结构,在查找时也有很好的性能.但是hash表不能提供有序遍历,这个是其特性决定,所以不足为奇.但是,更为实际的一个问题是如果遍历整个hash表中的所有元素? ...

  3. 1.Easy Touch 3.1

    Easy Touch 3.1 Hedgehog Team(导入 Easy Touch 插件时自动在菜单栏) Extensions: 拓展 Adding a new joytick: 虚拟摇杆 Addi ...

  4. 89. 格雷编码 (Medium)

    问题描述 89. 格雷编码 (Medium) n 位格雷码序列 是一个由 2ⁿ 个整数组成的序列,其中: 每个整数都在范围 [0, 2ⁿ - 1] 内(含 0 和 2ⁿ - 1) 第一个整数是 0 一 ...

  5. Django 知识点总结

    知识点总结 一.URL: 1.在python 正则表达式中,正则表达式命名组的语法是(?P<name>pattern),其中命名组中的命名就是name,并且pattern 是某些匹配的模式 ...

  6. antVue--a-cascader级联组件使用触发loadData方法注意事项

    <template> <a-cascader :options="options" :load-data="loadData" placeho ...

  7. javaweb自学书籍推荐

    第一部分:Java语言篇 1.<Java编程规范> 适合对象:初级.中级 介绍:这本书的作者是被誉为Java之父的James Gosling,入门者推荐阅读,对基础的讲解很不错. 2.&l ...

  8. mongodb添加删除节点及仲裁节点

    温馨提示:此mongodb版本为5.0.11 ,并注意,如果要删除节点,可以直接删除,添加节点前要先删除仲裁节点. rs.remove("192.168.0.180:27017") ...

  9. Ubuntu20.04 TLS 开机卡在“A start job is running for wait for network to be Configured”解决

    问题: 安装ubuntu20.04 TLS系统后,开机卡在"A start job is running for wait for network to be Configured" ...

  10. [iOS] 对 UItableView 等界面(ClipsToBounds) 同时使用 圆角和阴影

    展示内容的界面会被 ClipsToBounds = YES(按边缘剪切),但同时需要圆角和阴影效果. 一个界面,ClipsToBounds = YES 之后,阴影会被剪切,不再展示. 感觉只能使用多个 ...