第十一章 AtomicInteger源码解析

1、原子类

  • 可以实现一些原子操作
  • 基于CAS

下面就以AtomicInteger为例。

 

2、AtomicInteger

在没有AtomicInteger之前,对于一个Integer的线程安全操作,是需要使用同步锁来实现的,当然现在也可以通过ReentrantLock来实现,但是最好最方便的实现方式是采用AtomicInteger。

具体示例:

package com.collection.test;import java.util.concurrent.atomic.AtomicInteger;/*** 原子类的测试*/
public class AtomicTest {private static AtomicInteger atomicInteger = new AtomicInteger();//获取当前值public static void getCurrentValue(){System.out.println(atomicInteger.get());//-->0
    }//设置value值public static void setValue(){atomicInteger.set(12);//直接用12覆盖旧值System.out.println(atomicInteger.get());//-->12
    }//根据方法名称getAndSet就知道先get,则最后返回的就是旧值,如果get在后,就是返回新值public static void getAndSet(){System.out.println(atomicInteger.getAndSet(15));//-->12
    }public static void getAndIncrement(){System.out.println(atomicInteger.getAndIncrement());//-->15
    }public static void getAndDecrement(){System.out.println(atomicInteger.getAndDecrement());//-->16
    }public static void getAndAdd(){System.out.println(atomicInteger.getAndAdd(10));//-->15
    }public static void incrementAndGet(){System.out.println(atomicInteger.incrementAndGet());//-->26
    }public static void decrementAndGet(){System.out.println(atomicInteger.decrementAndGet());//-->25
    }public static void addAndGet(){System.out.println(atomicInteger.addAndGet(20));//-->45
    }public static void main(String[] args) {AtomicTest test = new AtomicTest();test.getCurrentValue();test.setValue();//返回旧值系列
        test.getAndSet();test.getAndIncrement();test.getAndDecrement();test.getAndAdd();//返回新值系列
        test.incrementAndGet();test.decrementAndGet();test.addAndGet();}
}
View Code

源代码:

    private volatile int value;// 初始化值/*** 创建一个AtomicInteger,初始值value为initialValue*/public AtomicInteger(int initialValue) {value = initialValue;}/*** 创建一个AtomicInteger,初始值value为0*/public AtomicInteger() {}/*** 返回value*/public final int get() {return value;}/*** 为value设值(基于value),而其他操作是基于旧值<--get()*/public final void set(int newValue) {value = newValue;}public final boolean compareAndSet(int expect, int update) {return unsafe.compareAndSwapInt(this, valueOffset, expect, update);}/*** 基于CAS为旧值设定新值,采用无限循环,直到设置成功为止* * @return 返回旧值*/public final int getAndSet(int newValue) {for (;;) {int current = get();// 获取当前值(旧值)if (compareAndSet(current, newValue))// CAS新值替代旧值return current;// 返回旧值
        }}/*** 当前值+1,采用无限循环,直到+1成功为止* @return the previous value 返回旧值*/public final int getAndIncrement() {for (;;) {int current = get();//获取当前值int next = current + 1;//当前值+1if (compareAndSet(current, next))//基于CAS赋值return current;}}/*** 当前值-1,采用无限循环,直到-1成功为止 * @return the previous value 返回旧值*/public final int getAndDecrement() {for (;;) {int current = get();int next = current - 1;if (compareAndSet(current, next))return current;}}/*** 当前值+delta,采用无限循环,直到+delta成功为止 * @return the previous value  返回旧值*/public final int getAndAdd(int delta) {for (;;) {int current = get();int next = current + delta;if (compareAndSet(current, next))return current;}}/*** 当前值+1, 采用无限循环,直到+1成功为止* @return the updated value 返回新值*/public final int incrementAndGet() {for (;;) {int current = get();int next = current + 1;if (compareAndSet(current, next))return next;//返回新值
        }}/*** 当前值-1, 采用无限循环,直到-1成功为止 * @return the updated value 返回新值*/public final int decrementAndGet() {for (;;) {int current = get();int next = current - 1;if (compareAndSet(current, next))return next;//返回新值
        }}/*** 当前值+delta,采用无限循环,直到+delta成功为止  * @return the updated value 返回新值*/public final int addAndGet(int delta) {for (;;) {int current = get();int next = current + delta;if (compareAndSet(current, next))return next;//返回新值
        }}/*** 获取当前值*/public int intValue() {return get();}
View Code

说明:使用与源代码都简单到爆了!自己看看注释。

注意:

  • value是volatile的,关于volatile的相关内容见《附2 volatile》,具体链接:http://www.cnblogs.com/java-zhao/p/5125698.html
  • 单步操作:例如set()是直接对value进行操作的,不需要CAS,因为单步操作就是原子操作。
  • 多步操作:例如getAndSet(int newValue)是两步操作-->先获取值,在设置值,所以需要原子化,这里采用CAS实现。
  • 对于方法是返回旧值还是新值,直接看方法是以get开头(返回旧值)还是get结尾(返回新值)就好
  • CAS:比较CPU内存上的值是不是当前值current,如果是就换成新值update,如果不是,说明获取值之后到设置值之前,该值已经被别人先一步设置过了,此时如果自己再设置值的话,需要在别人修改后的值的基础上去操作,否则就会覆盖别人的修改,所以这个时候会直接返回false,再进行无限循环,重新获取当前值,然后再基于CAS进行加减操作。
  • 如果还是不懂CAS,类比数据库的乐观锁

补充一个东西:

 1     // setup to use Unsafe.compareAndSwapInt for updates
 2     private static final Unsafe unsafe = Unsafe.getUnsafe();
 3     private static final long valueOffset;
 4 
 5     static {
 6         try {
 7             valueOffset = unsafe.objectFieldOffset
 8                 (AtomicInteger.class.getDeclaredField("value"));
 9         } catch (Exception ex) { throw new Error(ex); }
10     }
11 
12     private volatile int value;

这是AtomicInteger的所有属性,其中value存的是当前值,而当前值存放的内存地址可以通过valueOffset来确定。实际上是“value字段相对Java对象的起始地址的偏移量”

1     public final boolean compareAndSet(int expect, int update) {
2         return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
3     }

CAS方法:通过对比“valueOffset上的value”与expect是否相同,来决定是否修改value值为update值。

转载于:https://www.cnblogs.com/java-zhao/p/5140158.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/491318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

趋势 | 2019年人工智能行业的25大趋势

来源&#xff1a;网易智能知名创投研究机构CB Insights调研了25种最大的AI趋势&#xff0c;以确定2019年该技术的下一步趋势&#xff0c;他们根据行业采用率和市场优势评估了每种趋势&#xff0c;并将其归类为必要、实验性、威胁性、暂时的。1胶囊网络将挑战最先进的图像识别算…

工业视觉系统相关知识和选型介绍(一):相机篇

工业视觉系统相关知识和选型介绍&#xff08;一&#xff09;&#xff1a;相机篇一、工业视觉系统二、工业相机三、关键名词解释四、工业相机选型五、工业相机品牌六、相机选型实例一、工业视觉系统 1.机器视觉就是用机器代替人眼来做测量和判断。机器视觉系统是指通过机器视觉…

终于看见光的速度了:每秒一万亿帧的相机,拍摄到光的运行状态!

来源&#xff1a;机械发明爱好者我是谁&#xff0c;我在哪&#xff0c;我看到了什么&#xff0c;不会是手电筒照射的吧&#xff08;光移动的时候是在标签里面的&#xff0c;所以不可能是手电筒照射的&#xff09;。这个就是传说的中的飞秒拍摄技术飞秒&#xff08;femtosecond&…

win10下TensorFlow-GPU安装(GTX1660+CUDA10+CUDNN7.4)

首先安装anaconda Anaconda下载地址&#xff1a;https://www.anaconda.com/download/ 注意在安装时勾上第一项&#xff1a; 安装CUDA10.0&#xff1a; CUDA下载地址&#xff1a;https://developer.nvidia.com/cuda-toolkit-archive 安装CUDA前会先运行一个系统检查&#xff…

工业视觉系统相关知识和选型介绍(二):镜头篇

工业视觉系统相关知识和选型介绍&#xff08;二&#xff09;&#xff1a;镜头篇一、工业镜头介绍二、 关键名词解释二、图解镜头基本参数三、镜头选型四、常用工业镜头品牌一、工业镜头介绍 镜头的基本功能就是实现光束变换&#xff08;调制&#xff09;&#xff0c;在机器视觉…

《科学美国人》评出2019年十大突破性技术

来源&#xff1a;科技日报日前&#xff0c;著名科普杂志《科学美国人》公布了2019年十大突破性技术榜单。榜上有名的既有“高深莫测”的新型核反应堆和DNA存储&#xff0c;也有“平易近人”的新型肥料和食品包装。科技日报记者梳理后发现&#xff0c;这十大技术可分为清洁环境、…

MFC 学习笔记(一):MFC单文档程序运行流程梳理与总结

MFC 学习笔记&#xff08;一&#xff09;&#xff1a;MFC单文档程序运行流程梳理与总结 1.MFC单文档程序运行流程 1.首先利用全局变量对象 theApp 启动应用程序 &#xff08;这是因为这个全局对象&#xff0c;基类CWinApp中 this 的指针才能指向这个对象。&#xff09; 2.调…

对话清华教授孙茂松:第三代人工智能要处理“可解释性”问题

来源&#xff1a;澎湃新闻正如人类会综合利用视觉、听觉、触觉、语言等信息&#xff0c;让人工智能&#xff08;AI&#xff09;从多角度、多模态、多学科学习自然语言也是清华大学人工智能研究院的目标与任务。2019年7月1日&#xff0c;清华大学人工智能研究院第八个研究中心&a…

QT学习笔记(一):VS2013 +QT 5.8 运行、编译问题解决

QT学习笔记&#xff08;一&#xff09;&#xff1a;VS2013 QT 5.8 运行、编译问题解决 jom: E:\C\4.QT\HelloWord\Makefile.Debug [debug\moc_predefs.h] Error 1 ‘cl’ 不是内部或外部命令&#xff0c;也不是可运行的程序 或批处理文件。 jom: E:\C\4.QT\HelloWord\Makefile…

使用清华镜像安装pytorch失败的解决方法

首先添加清华镜像至Anaconda仓库&#xff1a; conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ conda config --set show_channel_urls yes …

受精卵或非“生命起始”?网友:教材是不是要改了……

来源&#xff1a;中国新闻网一直以来&#xff0c;科学家们都认为&#xff0c;精卵结合受精以后就是生命。但是&#xff0c;最近中美胚胎学家的一项最新联合研究成果表明&#xff0c;人类受精卵存在两套独立纺锤体&#xff0c;即从精卵结合到发生第一次有丝分裂期间&#xff0c;…

利用Excel进行成对(配对)T检验

首先在Excel中添加数据分析工具 https://jingyan.baidu.com/article/c275f6ba74b69ee33d7567c8.html 在Excel添加要分析的两组数据&#xff1a; 点击数据——>数据分析&#xff0c;选择t-检验&#xff1a;平均值的成对二样本分析&#xff0c;分别选取两组要分析的数据和输…

垃圾要分类!我们的大脑如何处理垃圾呢?

来源&#xff1a;中国生物技术网最近&#xff0c;垃圾分类已经成了热点话题&#xff0c;但实行这一举措的最终目的还是为了保护我们赖以生存的地球环境。同样&#xff0c;大脑为了维持健康&#xff0c;也专门有一套自己的“垃圾清除系统”&#xff0c;即glymphatic&#xff08;…

QT学习笔记(三):Qt软件打包发布(QT5.8 _msvc2013_64+Win10_64)

QT学习笔记&#xff08;三&#xff09;&#xff1a;Qt软件打包发布&#xff08;QT5.8 _msvc2013_64Win10_64&#xff09;1.编译方式介绍&#xff1a;2.动态编译方式打包发布QT程序&#xff1a;方法一&#xff1a;手动复制方法二&#xff1a;使用工具问题&解决&#xff1a;环…

麦肯锡报告摘译:未来成功城市的14个特征

来源&#xff1a;TOP产业办公研究院【前言】&#xff1a;本文摘译自麦肯锡发布的一份研究报告。报告来源&#xff1a;McKinsey&Company Report: Thriving amid turbulence: Imagining the cities of the future. Authored by Jonathan Woetzel , Vineet Rajadhyaksha , Joe…

MATLAB编辑GUI界面

在命令窗口输入&#xff1a;guide 即可进入编辑 若要在GUI界面的一个面板上显示程序中随意给定的字符&#xff1a; 首先创建一个“可编辑文本”&#xff08;位于左侧工具栏&#xff09;&#xff1a; 双击该面板&#xff0c;弹出该面板的工具栏&#xff0c;设置“string”&am…

单个神经元不可靠!这项新研究推翻以往认知,感知的最大限制在于解码过程...

来源&#xff1a;凹非寺“单个神经元不可靠&#xff01;”一项关于神经元的研究&#xff0c;让众人看嗨了。这项研究通过在小鼠身上做实验&#xff0c;先展示了神经元“不靠谱”的一面&#xff1a;单个神经元两次对相同视觉刺激的反应&#xff0c;竟然是不一样的。对于神经元的…

(转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在

问题描述&#xff1a;在用vs生成MVC时若使用Internet应用程序为模版&#xff0c;项目建好后重新编译下无法通过&#xff0c;弹出错误&#xff1a; 解决方案&#xff1a;问题出来后&#xff0c;询问了身边很多人都是一头雾水&#xff0c;于是乎各种谷歌和百度&#xff0c;还好功…

QT学习笔记(四):Qt5+MSVC编译 中文字符显示乱码问题解决

QT学习笔记&#xff08;四&#xff09;&#xff1a;Qt5MSVC编译 中文字符显示乱码问题解决问题&#xff1a;1、解决方法一&#xff1a;2、解决方法二&#xff1a;3、解决方法三&#xff1a;4、解决方法四&#xff1a;结果显示&#xff1a;Qt5MSVC编译 中文字符显示乱码。 现在为…