这是我参考的一篇文章《基于CAS的乐观锁实现》,讲述的是一种需要CPU支持的执行技术CAS(Compare and Swap)。

首先理解什么是原子性操作,意思是不能再拆分的操作,例如改写一个值,读取一个值都属于原子性操作。

那么CAS是两个操作,先比较旧值,比较通过后再进行改写,这种连合操作合并成一个指令交给CPU,由CPU操作来确保这是一个原子性操作。

多线程同时改写同一个值时,每个线程携带自己的旧值和新值交给CPU改写,CPU的运行是按逐条指令运行,如果发现旧值不符合,线程就会收到改写失败回应。

public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}

因此AtomicInteger#incrementAndGet()方法里,会循环尝试使用compareAndSet(...)方法,直到成功为止。

相关的原子类所在包:java.util.concurrent.atomic

  • Atomic + Boolean/Integer/Long/Reference
    操作一个对应的类型对象
  • Atomic + Integer/Long/Reference + Array
    操作一个对应类型的数组

  • Atomic + Integer/Long/Reference + FieldUpdater
    操作一个对应类型的Field对象,类似反射方式改写对象字段

这里《AtomicStampedReference解决ABA问题》,讲述了原子类会出现ABA时带来的隐患,文中举了一个例子,一个单向的链表实现了堆栈操作,使用一个原子变量作为链头指针,现在链头是A,A的next是B。有两个线程分别是T1和T2,他们并发的操作如下:

  • T1:AB => B
  • T2:AB => B => 空 => D => CD => ACD

由于线程T1只认链头是不是A,如果是A,就会将链头指向B,因此可能会出现直接把ACD变成B,这就是ABA并发的隐患。

  • AtomicMarkableReference
    操作一个对象类型和boolean类型的二元组
  • AtomicStampedReference
    操作一个对象类型和int类型的二元组

虽然例子中链头指针是一个原子变量,会出现ABA的情况,但如果再增加一个原子变量,这个原子变量确保不会出现ABA的情况,两个原子变量作为二元组进行原子性操作,即使用AtomicStampedReference就可以有效解决这个ABA的隐患了。

以下是Java8增加的原子类:

  • Striped64
  • Long/Double + Adder
  • Long/Double + Accumulator

这里有两篇文章,内容是分析它们的源码:《从LongAdder 看更高效的无锁实现》《LongAdder和LongAccumulator》

源码有些复杂,我也没看完,Striped64是这项新原子类的基类,它提供的原理是,把一个原子数拆分成多个原子数,最后把这多个原子数合成一个数。换句话说,原本在一个数上做递增或者递减操作的,现在变成在多个数里,选择其中一个做做递增或递减操作,那么加起来的结果与原本方式的结果是等价的。虽然是等价,但它结算结果的过程,是需要把多个数加起来,这个过程已经不是线程安全了,所以它的应用场合相比原本方式会宽一点,原本方式所取出来的值可以作为唯一ID,但现在方式只能用于统计。试想,如果有1000个线程同时在统计同一个数据,那么原本方式的原子类,就会失败率上升,效率也会随之下降。但如果把1000个线程,分成10份,每100个线程统计同一个数据,那么产生10个数据,最后统计的结果就是这10个数据叠加一起的结果,失败率当然因份数的增加而减少,效率也自然有保障。

应用场合:高并发,统计数据。

多线程同步工具——CAS原子变量的更多相关文章

  1. 多线程同步工具——volatile变量

    关于volatile,找了一堆资料看,看完后想找一个方法去做测试,测了很久,感觉跟没有一样. 这本书<深入理解Java内存模型>,对volatile描述中有这样一个比喻的说法,如下代码所示 ...

  2. Java多线程并发编程之原子变量与非阻塞同步机制

    1.非阻塞算法 非阻塞算法属于并发算法,它们可以安全地派生它们的线程,不通过锁定派生,而是通过低级的原子性的硬件原生形式 -- 例如比较和交换.非阻塞算法的设计与实现极为困难,但是它们能够提供更好的吞 ...

  3. Java多线程同步工具类之CountDownLatch

    在过去我们实现多线程同步的代码中,往往使用join().wait().notiyAll()等线程间通信的方式,随着JUC包的不断的完善,java为我们提供了丰富同步工具类,官方也鼓励我们使用工具类来实 ...

  4. Java多线程同步工具类之Semaphore

    Semaphore信号量通常做为控制线程并发个数的工具来使用,它可以用来限制同时并发访问资源的线程个数. 一.Semaphore使用 下面我们通过一个简单的例子来看下Semaphore的具体使用,我们 ...

  5. C++11 多线程同步 互斥锁 条件变量

    在多线程程序中,线程同步(多个线程访问一个资源保证顺序)是一个非常重要的问题,Linux下常见的线程同步的方法有下面几种: 互斥锁 条件变量 信号量 这篇博客只介绍互斥量和条件变量的使用. 互斥锁和条 ...

  6. 多线程同步工具——Lock

    本文原创,转载请注明出处. 参考文章: <"JUC锁"03之 公平锁(一)> <"JUC锁"03之 公平锁(二)> 锁分独占锁与共享锁, ...

  7. Java多线程同步工具类之CyclicBarrier

    一.CyclicBarrier使用 CyclicBarrier从字面上可以直接理解为线程运行的屏障,它可以让一组线程执行到一个共同的屏障点时被阻塞,直到最后一个线程执行到指定位置,你设置的执行线程就会 ...

  8. 多线程同步工具——LockSupport

    用例1:子线程等待主线程发放许可! public static void main(String[] args) { Thread thread = new Thread(){ public void ...

  9. Java多线程-----原子变量和CAS算法

       原子变量      原子变量保证了该变量的所有操作都是原子的,不会因为多线程的同时访问而导致脏数据的读取问题      Java给我们提供了以下几种原子类型: AtomicInteger和Ato ...

随机推荐

  1. 【深入浅出jQuery】源码浅析--整体架构

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  2. C# - 值类型、引用类型&走出误区,容易错误的说法

    1. 值类型与引用类型小总结 1)对于引用类型的表达式(如一个变量),它的值是一个引用,而非对象. 2)引用就像URL,是允许你访问真实信息的一小片数据. 3)对于值类型的表达式,它的值是实际的数据. ...

  3. Mysql事务探索及其在Django中的实践(一)

    前言 很早就有想开始写博客的想法,一方面是对自己近期所学知识的一些总结.沉淀,方便以后对过去的知识进行梳理.追溯,一方面也希望能通过博客来认识更多相同技术圈的朋友.所幸近期通过了博客园的申请,那么今天 ...

  4. PHP设计模式(一)简单工厂模式 (Simple Factory For PHP)

    最近天气变化无常,身为程序猿的寡人!~终究难耐天气的挑战,病倒了,果然,程序猿还需多保养自己的身体,有句话这么说:一生只有两件事能报复你:不够努力的辜负和过度消耗身体的后患.话不多说,开始吧. 一.什 ...

  5. 体验报告:微信小程序在安卓机和苹果机上的区别

    很多人可能会问:微信小程序和在微信里面浏览一个网页有什么区别? 首先,小程序的运行是全屏的,界面跟进入了一个APP很像,更为沉浸跟在微信里面访问h5不一样:其次,它的浏览体验更为稳定. 不过,这还不够 ...

  6. iosselect:一个js picker项目,在H5中实现IOS的select下拉框效果

    具体文档和demo可以访问github:https://github.com/zhoushengmufc/iosselect 移动端浏览器对于select的展示样式是不一致的,ios下是类似原生的pi ...

  7. 总结30个CSS3选择器

    或许大家平时总是在用的选择器都是:#id  .class  以及标签选择器.可是这些还远远不够,为了在开发中更加得心应手,本文总结了30个CSS3选择器,希望对大家有所帮助. 1 *:通用选择器 ;; ...

  8. Android—自定义开关按钮实现

    我们在应用中经常看到一些选择开关状态的配置文件,做项目的时候用的是android的Switch控件,但是感觉好丑的样子………… 个人认为还是自定义的比较好,先上个效果图:

  9. Xamarin技术文档------VS多平台开发

    此技术业余时间研究,仅供大家学习参考,不涉及深入研究,有一定开发基础的人员,应该都能较快上手. 一.简介 Xamarin始创于2011年,旨在使移动开发变得难以置信地迅捷和简单.Xamarin的产品简 ...

  10. ABP框架理论研究总结(典藏版)

    目前,我已经完成了Module-Zero的翻译,请查看我的<Module-Zero学习目录>. 到现在为止,使用ABP框架开发正式项目已经3个月有余了,期间翻阅了大量文档资料,包括ABP官 ...