从CAS讲起,真正高性能解决并发编程的原子操作
今天是猿灯塔“365天原创计划”第1天。

一.原子性操作
原子性操作:原子性在一个操作是不可中断的,要么全部执行成功要么全部执行失败,有着“同生共死”的感觉。及时在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程所干扰。
上述代码中AtomicInteger.getAndIncrement()
就很好的帮我们在多线程业务场景中解决了原子性问题
深入源码底层发现它的方法源于:
继续深入:
发现实际上这个方法的实现原理就是CAS。
二.CAS
compare and swap 比较和交换
属于硬件同步原语属于CPU指令可以直接对内存做修改处理器提供了基本内存操作的原子性保证。看一下CAS原理图:
CAS需要有3个操作数:内存地址N,旧的预期值E,即将要更新的目标值N。
CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。
首先读取开始变量值N,存入变量E,然后在进行++操作,计算后的结果值存入变量V ,
然后在将E值写回,跟N值进行比较,如果此时E值与N值是一致,则这个操作直接结束,否则就要继续从开始部分重来一次,所以CAS也被成为自旋锁,或者说无锁。
JVM提供了一个工具类 Unsafe
Unsafe是CAS的核心类,由于java方法无法直接访问底层系统,需要通过本地(native)方法来访问,Unsafe相当于一个后门,基于该类可以直接操作特定内存的数据。Unsafe类存在于sun.misc包中,其内部方法操作可以像C的指针一样直接操作内存,因为java中CAS操作的执行依赖于Unsafe类的方法
如下就是代码演示:
三.ABA问题
ABA问题的根本在于cas在修改变量的时候,无法记录变量的状态,比如修改的次数,是否修改过这个变量。这样就很容易在一个线程将A修改成B时,另一个线程又会把B修改成A,造成casd多次执行的问题。
解决方案:AtomicStampReference
AtomicStampReference在cas的基础上增加了一个标记stamp,使用这个标记可以用来觉察数据是否发生变化,给数据带上了一种实效性的检验。它有以下几个参数:
//参数代表的含义分别是 期望值,写入的新值,期望标记,新标记值
publicbooleancompareAndSet(Vexpected,VnewReference,intexpectedStamp,intnewStamp);
public V getRerference();
public int getStamp();
publicvoidset(VnewReference,int newStamp);
代码我就不演示了~ 希望这篇文章对各位有帮助吧!!!
从CAS讲起,真正高性能解决并发编程的原子操作的更多相关文章
- 并发编程之原子操作Atomic&Unsafe
原子操作:不能被分割(中断)的一个或一系列操作叫原子操作. 原子操作Atomic主要有12个类,4种类型的原子更新方式,原子更新基本类型,原子更新数组,原子更新字段,原子更新引用.Atomic包中的类 ...
- Java并发编程之原子操作类
什么是原子操作类当更新一个变量的时候,多出现数据争用的时候可能出现所意想不到的情况.这时的一般策略是使用synchronized解决,因为synchronized能够保证多个线程不会同时更新该变量.然 ...
- java并发编程之原子操作
先来看一段简单的代码,稍微有点并发知识的都可以知道打印出结果必然是一个小于20000的值 package com.example.test.cas; import java.io.IOExceptio ...
- C++11并发编程:原子操作atomic
一:概述 项目中经常用遇到多线程操作共享数据问题,常用的处理方式是对共享数据进行加锁,如果多线程操作共享变量也同样采用这种方式. 为什么要对共享变量加锁或使用原子操作?如两个线程操作同一变量过程中,一 ...
- c++并发编程之原子操作的实现原理
原子(atomic)本意是”不能被进一步分割的最小粒子”,而原子操作(atomic operation)意为”不可被中断的一个或一系列操作”. 处理器如何实现原子操作 (1) 使用总线锁保证原子性 如 ...
- 王家林系列之scala--第69讲:Scala并发编程react、loop代码实战详解
刚才看了一下,群里王家林老师又更新课程了,真为王老师的勤奋感到佩服,于是迫不及待的下载下来观看学习.本期讲的是关于scala并发编程的react.loop代码实战. 信息来源于 DT大数据梦工厂微信公 ...
- 深入解析ConcurrentHashMap:感受并发编程智慧
如果有一个整型变量count,多个线程并发让count自增1,你会怎么设计? 你知道如何让多个线程协作完成一件事件吗? 前言 很高兴遇见你~ ConcurrentHashMap是个老生常谈的集合类了, ...
- 并发编程(一)—— volatile关键字和 atomic包
本文将讲解volatile关键字和 atomic包,为什么放到一起讲呢,主要是因为这两个可以解决并发编程中的原子性.可见性.有序性,让我们一起来看看吧. Java内存模型 JMM(java内存模型) ...
- Java并发编程实战(3)- 互斥锁
我们在这篇文章中主要讨论如何使用互斥锁来解决并发编程中的原子性问题. 目录 概述 互斥锁模型 互斥锁简易模型 互斥锁改进模型 Java世界中的互斥锁 synchronized中的锁和锁对象 synch ...
随机推荐
- Python报错:SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape
运行python文件的时候报错: SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2 ...
- 深入理解JVM(③)各种垃圾收集算法
前言 从如何判定对象消亡的角度出发,垃圾收集算法可以划分为"引用计数式垃圾收集"(Reference Counting GC)和"追踪式垃圾收集"(Tracin ...
- Python使用wxpy模块实现微信两两群组消息同步
python使用wxpy模块提供的微信API接口实现两两群组的消息同步 安装模块: pip install wxpy 注意:需要同步的微信群需要保存到通讯录中 以下是自己闲来无事写的代码,暂时还存在以 ...
- 【JAVA进阶架构师指南】之五:JVM性能调优
前言 首先给大家说声对不起,最近属实太忙了,白天上班,晚上加班,回家还要收拾家里,基本每天做完所有事儿都是凌晨一两点了,没有精力再搞其他的了. 好了,进入正题,让我们来聊聊JVM篇最后一个章节 ...
- Hexo博客框架攻略
前言 前天无意在b站看到up主CodeSheep上传的博客搭建教程,引起了我这个有需求但苦于没学过什么博客框架的小白的兴趣.于是花了两天时间终于终于把自己的博客搭建好了,踩了无数的坑,走偏了无数的路, ...
- 3 年经验的 Java 后端妹子,横扫阿里、滴滴、美团,整理出这份厚厚的 8000 字面经!
自序 这次面试的公司有一点点多,主要是因为毕业后前两份工作找的都很草率,这次换工作就想着,emm,毕业三年了,该找个工作好好沉淀几年了. 先说下这次面试的结果吧: 到 hr 面的:阿里.美团.滴滴.金 ...
- startActivityForResult调用另外一个Activity获取返回结果
startActivityForResult(intent,requestCode)可以调用另外一个Activity,并返回结果. 换头像案例 activity_main.xml <?xml v ...
- 【Java思考】Java 中的实参与形参之间的传递到底是值传递还是引用传递呢?
科普: 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数. 引用传递(pass by reference)是指在 ...
- 初识Java Java基础知识
今天给大家带来的是初级Java基础部分的知识:包括初识Java.变量.常量.数据类型.运算符.各种选择结构.循环结构.数组等Java的基础语法部分!!!内容.步骤超详细,附有各种案例的源代码(可以直接 ...
- 【初学Java学习笔记】AOP与OOP
AOP(Aspect Oriented Programming) 面向切面编程,是属于Spring框架中的内容.AOP相当于OOP的补充,当我们需要对多个对象引入一个公共行为,比如日志,操作记录等,就 ...