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. 6.配置git-码云仓库

    使用git需要使用码云或者github,github存在访问慢的情况,所以我使用码云(gitee). git客户端 下载安装 到git官网  https://git-scm.com/ 下载git客户端 ...

  2. CF850F 题解

    题意 传送门 有一袋 \(n\) 个颜色球,第 \(i\) 个颜色的球有 \(a_i\) 个. 当袋子里至少有两个不同颜色的球时,执行以下步骤: 一个接一个的按照顺序随机取出两个的球,这些球的颜色可能 ...

  3. JS学习-Canvas

    Canvas Canvas API 提供了一个通过JavaScript 和 HTML的<canvas>元素来绘制图形的方式.它可以用于动画.游戏画面.数据可视化.图片编辑以及实时视频处理等 ...

  4. Unity 热更新XLua

    什么是冷更新 开发者将测试好的代码,发布到应用商店的审核平台,平台方会进行稳定性及性能 测试.测试成功后,用户即可在AppStore看到应用的更新信息,用户点击应用更 新后,需要先关闭应用,再进行更新 ...

  5. Google Chrome 离线安装包官方下载

    我们参照 Google Chrome帮助中的<下载和安装 Google Chrome>,在这里找到官方最新版离线安装包的下载地址:备用 Chrome 安装程序,历史版本请通过版本号的方式下 ...

  6. 华硕推出无风扇迷你电脑 PL64-明显是奔着软路由去的

    看这个配置,做客厅软路由再合适不过了.要是针对客厅的影音需求,CPU性能以及对大容量存储的刚需,这个还是有些欠缺. IT之家 12 月 17 日消息,华硕 PL 系列迷你电脑现已迎来最新一代机型,其中 ...

  7. vue+antd实现PDF预览(后端返回的是文件流)

    操作步骤: 第一步:下载包   npm install --save vue-pdf 第二步:导入组件 第三步:使用pdf标签进行展示,showUrl指的是访问路径 第四步:定义要用到的变量 第五步: ...

  8. mysql之数据表基本操作-第四篇

    在关系型数据库中,数据表是一系列二维数组的集合,用来存储数据和操作数据的逻辑结构. 1.创建表,以创建一个简单的员工表为例: create table employee ( empId INT(11) ...

  9. oracle相关知识

    1. 给表字段添加注释的语法 comment on column 表名.字段名 is '注释信息'; 2. 数据库字段重命名 alter table ORGAN_PARTER_EXT_TWO rena ...

  10. qt的其他窗口

    一.qt的其他类族 2.Qlabel ui->setupUi(this); QFont font;//确立一个字体对象 font.setFamily("华文行楷");//字体 ...