原文连接:(http://www.studyshare.cn/blog-front/blog/details/1166/0 )
一、原子操作是什么?

如果有两个线程分别执行两个操作A和B,从第一个线程执行A操作的角度来看,另外一个线程执行B操作,要么将B操作执行完,要么B操作

压根儿不执行,那么A操作和B操作对彼此来讲就是原子的。

二、原子操作如何实现?

1、使用锁:锁机制就是将一个操作执行完毕后,其他操作获取锁然后继续执行,通过对多个操作进行隔离,从而实现原子操作。

2、CAS:CAS是Compare And Swap的简称,即:比较并交换。这是当前的处理器基本都支持的一种指令。每个CAS指令包括三个运算符,

一个内存地址V,一个期望值A和一个新值B,CAS指令执行的时候是去判断这个地址V上的值和期望值A是否相等,相等则将地址V上的值修

改为新值B,不等则不作任何操作。CAS操作实际实现是在一个循环中不断执行CAS指令,直到成功为止。

三、为什么要使用原子操作?

1、我们知道原子操作可以通过锁来实现,但锁是一种粗粒度的操作,使用锁会存在一些问题,例如:(1)当一个线程占用了锁资源,其他

线程就被阻塞,然而被阻塞的线程的优先级又很高。此时也只能等待锁释放。如果获得锁的线程一致不释放的话那情况就更糟糕了。(2)如

果有大量的线程来竞争资源,那么CPU就需要花费大量的时间和资源来处理这些竞争。这对CPU这种稀缺资源是不利的。

2、如果我们要实现一个多线程下的程序计数器。使用锁机制无疑是笨重的。那么CAS就能很好的解决这种需求。

3、JDK的源码中非常多的类中都使用了CAS操作,了解并清楚CAS操作对阅读JDK源码是必要的。

四、CAS如何实现线程安全?

CAS实现线程安全不在代码层面处理,而是交给硬件-CPU和内存,利用CPU的多处理能力,实现硬件层面的阻塞,然后加上volidate变量的

特性即可实现基于原子操作的线程安全。

五、CAS实现原子操作的三大问题

1、ABA问题:因为CAS在操作值的时候先要检查值有没有发生变化,如果没有发生变化则更新,那么所谓ABA问题就是当原来的值是A,改变

成B,然后又改变成A,那么CAS检查的时候发现值还是初始的A,并没有发生变化。然后实际上却是已经变化了。如何解决ABA问题:加版本

号,即在A变成B再变成A的时候,每一步操作加一个version,即:1A->2B->3A,这样就可以根据版本号是否有变化即可判断是否发生了ABA问题。

2、循环时间长、开销大:上面说过是在一个循环中不断执行CAS指令(自旋CAS),如果长时间都不成功的话,则会对CPU带来很大的执行开销。

3、只能保证一个共享变量的原子操作:即一个CAS操作只能保证一个共享变量的的原子性。如果有多个共享变量则不能使用CAS操作,可使用

锁。也可以将多个共享变量合并然后使用CAS操作。java1.5之后提供了AtomicReference类来保证引用对象之间的原子性。可以将多个变量放进

一个对象中然后进行CAS操作。

六、JDK中常见原子操作类的使用

1、AtomicInteger

•int addAndGet(int delta):以原子方式将输入的数值与实例中的值(AtomicInteger里的value)相加,并返回结果。

•boolean compareAndSet(int expect,int update):如果输入的数值等于预期值,则以原子方式将该值设置为输入的值。

•int getAndIncrement():以原子方式将当前值加1,注意,这里返回的是自增前的值。

•int getAndSet(int newValue):以原子方式设置为newValue的值,并返回旧值。

2、AtomicIntegerArray

主要是提供原子的方式更新数组里的整型,其常用方法如下。

•int addAndGet(int i,int delta):以原子方式将输入值与数组中索引i的元素相加。

•boolean compareAndSet(int i,int expect,int update):如果当前值等于预期值,则以原子方式将数组位置i的元素设置成update值。

需要注意的是,数组value通过构造方法传递进去,然后AtomicIntegerArray会将当前数组复制一份,所以当AtomicIntegerArray对内部的数组元

素进行修改时,不会影响传入的数组。

3、AtomicReference

原子更新引用类型,更多具体使用可查看jdk文档

更多原子操作类,在jdk文档java.util.concurrent.atomic包下。

原创文章,转载请注明出处。
java开发工具下载地址及安装教程大全,点这里
更多深度技术文章,在这里

原子操作CAS-最小的线程安全的更多相关文章

  1. java并发编程系列二:原子操作/CAS

    什么是原子操作 不可被中断的一个或者一系列操作 实现原子操作的方式 Java可以通过锁和循环CAS的方式实现原子操作 CAS( Compare And Swap )  为什么要有CAS? Compar ...

  2. Java并发编程(十一)——原子操作CAS

    一.原子操作 syn基于阻塞的锁的机制,1.被阻塞的线程优先级很高,2.拿到锁的线程一直不释放锁怎么办?3.大量的竞争,消耗cpu,同时带来死锁或者其他安全. CAS的原理 CAS(Compare A ...

  3. java原子操作CAS

    本次内容主要讲原子操作的概念.原子操作的实现方式.CAS的使用.原理.3大问题及其解决方案,最后还讲到了JDK中经常使用到的原子操作类. 1.什么是原子操作? 所谓原子操作是指不会被线程调度机制打断的 ...

  4. 原子操作cas

    一.概念, 基于处理器指令,把比较和交换合成一个指令完成,保证了原子性: 因为是针对一个内存地址值的,一个内存地址指向一个变量,所以只对一个共享变量能保证原子性: 二.原子操作类 锁只有synchro ...

  5. 并发之ATOMIC原子操作--CAS乐观锁原理(二)

    1.乐观锁介绍 程序完成并发操作时,访问数据时每次不加锁,假设没有冲突去完成某项操作,如果因为冲突失败就重试,直到成功为止.就是当去做某个修改或其他操作的时候它认为不会有其他线程来做同样的操作(竞争) ...

  6. hbase 原子操作cas

    在高并发的情况下,对数据row1  column=cf1:qual1, timestamp=1, value=val1的插入或者更新可能会导致非预期的情况, 例如:原本客户端A需要在value=val ...

  7. CAS 原子操作

    理会CAS和CAS: 有时候面试官面试问你的时候,会问,谈谈你对CAS的理解,这时应该有很多人,就会比较懵,当然,我也会比较懵,当然我和很多人的懵不同,很多人可能,并不知道CAS是一个什么东西,而在我 ...

  8. 【C# 线程】并发编程的基石——CAS机制

    其实Java并发框架的基石一共有两块,一块是本文介绍的CAS,另一块就是AQS,后续也会写博客介绍. 什么是CAS机制 CAS机制是一种数据更新的方式.在具体讲什么是CAS机制之前,我们先来聊下在多线 ...

  9. C++线程同步之原子操作

    所谓的原子操作就是指一个线程对于某一个资源做操作的时候能够保证没有其它的线程能够对此资源进行访问. 原子操作仅仅能够解决某一个变量的问题,只能使得一个整型数据做简单算术运算的时候是原子的. 以下案例需 ...

随机推荐

  1. android隐藏显示小键盘

    记录一下开发中虚拟键盘的使用,fragment和activity中不同的使用 fragment下点击其它位置隐藏小键盘,复制到initView()方法中 view.setOnTouchListener ...

  2. python3实现万年历(包括公历、农历、节气、节日)

    #!/usr/local/bin/python3 # coding=utf-8 # Created: 20/07/2012 # Copyright: http://www.cnblogs.com/tx ...

  3. 微软输入法TSF SampleIME 代码浅说

    原文:微软输入法TSF SampleIME 代码浅说 微软提供了一个简单的TSF拼音输入法的示例SampleIME,主要的问题是:不支持数字键选候选字,不能自动上屏,没有联想功能.在笔者开发动态输入法 ...

  4. Android在putString和getString使用方法

    函数: putString(String key,String value); 功能:将键为key的值为value. 详细的容器详细考虑比如对于Editor 的对象来讲: 代码例如以下: 首先新建一个 ...

  5. WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探

    原文:WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探         最近因为项目需要,开始学习如何使用WPF开发桌面程序.使用WPF一段时间之后,感 ...

  6. Code First 连接已有数据库

    连接数据库                 生成结果并没有一个可视化界面(Model First有)     其他 连接数据库之后,可以采用migration管理第一次add-migration XX ...

  7. WPF Binding妙处-既无Path也无Source

    <Window x:Class="XamlTest.Window12"        xmlns="http://schemas.microsoft.com/win ...

  8. 数组/LINQ/List/ObservableCollection

    private static void AddIndustryTypes(sectorCode[] result) { var industryTypes = (from t in result se ...

  9. SQLite 的版本问题

    原文:SQLite 的版本问题 在SQLite官方网站上的下载包真可以看花眼.不同的.net版本,还有不同的平台,开发和发布时需要加以注意. 在网上搜了搜,早有人注意到了. 关于在.Net开发中使用S ...

  10. 分配粒度和内存页面大小(x86处理器平台的分配粒度是64K,内存页是4K,所以section都是0x1000对齐,硬盘扇区大小是512字节,所以PE文件默认文件对齐是0x200)

    分配粒度和内存页面大小 x86处理器平台的分配粒度是64K,32位CPU的内存页面大小是4K,64位是8K,保留内存地址空间总是要和分配粒度对齐.一个分配粒度里包含16个内存页面. 这是个概念,具体不 ...