采用硬件提供原子操作指令实现的,即CAS。每次调用都会先判断预期的值是否符合,才进行写操作,保证数据安全。

CAS机制

CAS是英文单词Compare And Swap的缩写,翻译过来就是比较并替换。CAS机制当中使用了3个基本操作数:

(1)内存地址V,也就是AtomicInteger中的valueOffset。

(2)旧的预期值A,也就是getAndIncrement方法中的current。

(3)要修改的新值B,也就是getAndIncrement方法中的next。

CAS机制中,更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。下面我们来看一个具体的例子:

(1)在内存地址V当中,存储着值为10的变量。

(2)此时线程1想要把变量的值增加1。对线程1来说,旧的预期值A=10,要修改的新值B=11。

(3)但是,在线程1要提交更新之前,另一个线程2抢先一步,把内存地址V中的变量值率先更新成了11。

(4)此时,线程1开始提交更新,首先进行A和地址V的实际值比较(Compare),发现A不等于V的实际值,提交失败。

(5)线程1重新获取内存地址V的当前值,并重新计算想要修改的新值。此时对线程1来说,A=11,B=12。这个重新尝试的过程被称为自旋。

(6)这一次比较幸运,没有其他线程改变地址V的值。线程1进行Compare,发现A和地址V的实际值是相等的。

(7)线程1进行替换,把地址V的值替换为B,也就是12。

对比Synchronized,我们可以发现,Synchronized属于悲观锁,悲观地认为程序中的并发情况严重,所以严防死守。CAS属于乐观锁,乐观地认为程序中的并发情况不那么

严重,所以让线程不断去尝试更新。

但是CAS机制通常也存在以下缺点:

(1)ABA问题

如果V的初始值是A,在准备赋值的时候检查到它仍然是A,那么能说它没有改变过吗?也许V经历了这样一个过程:它先变成了B,又变成了A,使用CAS检查时

以为它没变,其实却已经改变过了;则可以加上版本号:1A-2B-3A

(2)CPU开销较大

在并发量比较高的情况下,如果许多线程反复尝试更新某一个变量,却又一直更新不成功,循环往复,会给CPU带来很大的压力。

(3)不能保证代码块的原子性

CAS机制所保证的只是一个变量的原子性操作,而不能保证整个代码块的原子性。比如需要保证3个变量共同进行原子性的更新,就不得不使用Synchronized了。

java的原子类 AtomicInteger 实现原理是什么?的更多相关文章

  1. 对Java原子类AtomicInteger实现原理的一点总结

    java原子类不多,包路径位于:java.util.concurrent.atomic,大致有如下的类: java.util.concurrent.atomic.AtomicBoolean java. ...

  2. Java原子类AtomicInteger实现原理的一点总结

    java原子类不多,包路径位于:java.util.concurrent.atomic,大致有如下的类: java.util.concurrent.atomic.AtomicBoolean java. ...

  3. java 线程 原子类相关操作演示样例 thinking in java4 文件夹21.3.4

    java 线程  原子类相关操作演示样例 package org.rui.thread.volatiles; import java.util.Timer; import java.util.Time ...

  4. Java原子类及内部原理

    一.引入 原子是世界上的最小单位,具有不可分割性.比如 a=0:(a非long和double类型) 这个操作是不可分割的,那么我们说这个操作是原子操作.再比如:a++: 这个操作实际是a = a + ...

  5. (转)Java atomic原子类的使用方法和原理(一)

    在讲atomic原子类之前先看一个小例子: public class UseAtomic { public static void main(String[] args) { AtomicIntege ...

  6. Java并发—原子类,java.util.concurrent.atomic包(转载)

    原子类 Java从JDK 1.5开始提供了java.util.concurrent.atomic包(以下简称Atomic包),这个包中 的原子操作类提供了一种用法简单.性能高效.线程安全地更新一个变量 ...

  7. juc原子类之二:基本类型原子类AtomicInteger(AtomicLong、AtomicBoolean)

    一.AtomicInteger简介 AtomicInteger, AtomicLong和AtomicBoolean这3个基本类型的原子类的原理和用法相似.以AtomicInteger对基本类型的原子类 ...

  8. java并发:原子类之AtomicLong

    原子类之AtomicLong java线程中的操作,需要满足原子性.可见性等原则,比如i++这样的操作不具备原子性, A线程读取了i,另一个线程执行i++,A线程再执行i++就会引发线程安全问题 推荐 ...

  9. JUC包-原子类(AtomicInteger为例)

    目录 JUC包-原子类 为什么需要JUC包中的原子类 原子类原理(AtomicInteger为例) volatile CAS CAS的缺点 ABA问题 什么是ABA问题 ABA问题的解决办法 JUC包 ...

随机推荐

  1. code block自动生成makefile

    安装插件 http://developer.berlios.de/projects/cbmakegen/  然后会在project菜单下面有一个Generate Makefile的选项 点击就行了 如 ...

  2. mac下面 ,启动2个桌面版appium的方法

    分别打开2个终端,分别输入 appium 就可以分别起2个appium桌面版,然后设置端口 即可 参考: https://blog.csdn.net/qq_15283475/article/detai ...

  3. Charles问题

    1.内容显示乱码 1.1.使用Charles抓包,text显示乱码,note提示如下 SSL Proxying not enabled for this host: enable in Proxy S ...

  4. ARM Cortex-A9 (tiny 4412)

    要求 移植linux增加系统调用并烧写至开发板 详细步骤 一.搭建linux编译环境 1.GCC 编译器的安装: tar xzvf arm-linux-gcc-4.5.1-v6-vfp-2012030 ...

  5. delphi HTML转义字符编码转换

    网上很多把HTML转换成纯文本格式的方法很多思路都是用正则表达式或者分析html代码替换的方法. 本文是利用IE完成转换,即利用IHTMLDocument2接口. Denon天Denon龙Denon ...

  6. 对mysql事务提交、回滚的错误理解

    一.起因 begin或者START TRANSACTION开始一个事务 rollback事务回滚 commit 事务确认 人们对事务的解释如下:事务由作为一个单独单元的一个或多个SQL语句组成,如果其 ...

  7. CSS部分

    float属性 父级坍塌现象 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  8. courator - create

    0. retry policy RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000,3); 1. client 1) recipes ...

  9. django-request获取数据

    request 如果说 urls.py 是 Django 中前端页面和后台程序桥梁,那么 request 就是桥上负责运输的小汽车 可以说后端接收到的来至前端的信息几乎全部来自于requests中. ...

  10. crawlspider 多分页处理

    提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基 ...