AtomicInteger源码

在java.util.concurrent.atomic包下提供了大量的原子类,这里以AtomicInteger源码为例,添加了一些注释,个人理解,供参考;

其中比较重要的一个概念是CAS操作,现代CPU已广泛支持,在JDK的AtomicInteger类中是调用了Unsafe类的compareAndSwapInt方法实现的,代码(jdk1.7.0_79)如下:

package java.util.concurrent.atomic;
import sun.misc.Unsafe; public class AtomicInteger extends Number implements java.io.Serializable {
//序列化相关
private static final long serialVersionUID = 6214790243416807050L; // JDK里使用的一个工具类对象,提供一些不安全的操作的方法,一般不会在自己的程序中使用该类
//在这里主要用到其中的objectFieldOffset、putOrderedInt、compareAndSwapInt方法
private static final Unsafe unsafe = Unsafe.getUnsafe(); //value成员属性的内存地址相对于对象内存地址的偏移量
private static final long valueOffset; static {
try {
//初始化valueOffset,通过unsafe.objectFieldOffset方法获取成员属性value内存地址相对于对象内存地址的偏移量
valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
//int的值,设为volatile,保证线程之间的可见性
private volatile int value; /**
* 构造方法,传入指定int值
*
* @param initialValue the initial value
*/
public AtomicInteger(int initialValue) {
value = initialValue;
} /**
* 构造方法,使用默认值0
*/
public AtomicInteger() {
} /**
* 获取int值
*/
public final int get() {
return value;
} /**
* 设为指定值
*/
public final void set(int newValue) {
value = newValue;
} /**
* 最终设为指定值,但其它线程不能马上看到变化,会延时一会
*/
public final void lazySet(int newValue) {
unsafe.putOrderedInt(this, valueOffset, newValue);
} /**
* 以原子方式设置为给定值,并返回旧值
*/
public final int getAndSet(int newValue) {
//乐观锁,非阻塞同步方式,循环调用compareAndSet,直到成功
for (;;) {
int current = get();
//CAS操作,期待值current与内存中的值比较,相等的话设为newValue值
//否则下个循环,调用get()获取current值,继续执行CAS操作直到成功
if (compareAndSet(current, newValue))
return current;
}
} /**
* CAS操作,现代CPU已广泛支持,是一种原子操作;
* 简单地说,当期待值expect与valueOffset地址处的值相等时,设置为update值
*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
} /**
* 查看源码,与compareAndSet方法一致,不解??
*/
public final boolean weakCompareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
} /**
* 原子操作,自增,返回旧值
*/
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
} /**
* 原子操作,自减,返回旧值
*/
public final int getAndDecrement() {
for (;;) {
int current = get();
int next = current - 1;
if (compareAndSet(current, next))
return current;
}
} /**
* 原子操作,加上一个数,返回旧值
*/
public final int getAndAdd(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return current;
}
} /**
* 原子操作,自增,返回新值
*/
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
} /**
* 原子操作,自减,返回新值
*/
public final int decrementAndGet() {
for (;;) {
int current = get();
int next = current - 1;
if (compareAndSet(current, next))
return next;
}
} /**
* 原子操作,加上一个数,返回新值
*/
public final int addAndGet(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return next;
}
} /**
* Returns the String representation of the current value.
* @return the String representation of the current value.
*/
public String toString() {
return Integer.toString(get());
} public int intValue() {
return get();
} public long longValue() {
return (long)get();
} public float floatValue() {
return (float)get();
} public double doubleValue() {
return (double)get();
} }

AtomicInteger源码注释的更多相关文章

  1. AtomicInteger源码分析——基于CAS的乐观锁实现

    AtomicInteger源码分析——基于CAS的乐观锁实现 1. 悲观锁与乐观锁 我们都知道,cpu是时分复用的,也就是把cpu的时间片,分配给不同的thread/process轮流执行,时间片与时 ...

  2. JDK AtomicInteger 源码分析

    @(JDK)[AtomicInteger] JDK AtomicInteger 源码分析 Unsafe 实例化 Unsafe在创建实例的时候,不能仅仅通过new Unsafe()或者Unsafe.ge ...

  3. 并发-AtomicInteger源码分析—基于CAS的乐观锁实现

    AtomicInteger源码分析—基于CAS的乐观锁实现 参考: http://www.importnew.com/22078.html https://www.cnblogs.com/mantu/ ...

  4. 鸿蒙内核源码分析(源码注释篇) | 鸿蒙必定成功,也必然成功 | 百篇博客分析OpenHarmony源码 | v13.02

    百篇博客系列篇.本篇为: v13.xx 鸿蒙内核源码分析(源码注释篇) | 鸿蒙必定成功,也必然成功 | 51.c.h .o 几点说明 kernel_liteos_a_note | 中文注解鸿蒙内核 ...

  5. AtomicInteger源码分析

    问题背景 最近在看LinkedBlockingQueue看到了其中的count使用AtomicInteger修饰,之前也看过AtomicInteger的一些解释,也是似懂非懂的,今天深入的了解了其实现 ...

  6. lesson8:AtomicInteger源码解析及性能分析

    AtomicInteger等对象出现的目的主要是为了解决在多线程环境下变量计数的问题,例如常用的i++,i--操作,它们不是线程安全的,AtomicInteger引入后,就不必在进行i++和i--操作 ...

  7. 简易富文本编辑器bootstrap-wysiwyg源码注释

    好久没写随笔了,因为最近比较忙,小公司基本都是一个前端干所有属于和部分不属于前端的事情,所以就没空弄了,即使想分享,也因为没有时间和精力就搁置了. 这周周六日休息,正好时间比较充裕(ps:目前处在单休 ...

  8. WebBench压力测试工具(详细源码注释+分析)

    本文适合人群:对WebBench实现感兴趣的人 WebBench原理: Linux下使用的服务器压力测试工具,利用fork建立多个子进程,每个子进程在测试时间内不断发送请求报文,建立多个连接,然后由父 ...

  9. BackboneJS 源码注释

    Backbone 作者在源码中做了很好的注释,这里只是锦上添花,补充一些个人的理解而已. // Backbone.js 1.2.3 // (c) 2010-2015 Jeremy Ashkenas, ...

随机推荐

  1. 项目安排(离散化+DP)

    题目来源:网易有道2013年校园招聘面试二面试题 题目描述: 小明每天都在开源社区上做项目,假设每天他都有很多项目可以选,其中每个项目都有一个开始时间和截止时间,假设做完每个项目后,拿到报酬都是不同的 ...

  2. 高级javascript---模块化编程

    随着网站逐渐变成“互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂 网页越来越像桌面程序,需要一个团队分工协作.进度管理.单元测试等等......开发者不得不使用软 ...

  3. Java (JVM) Memory Model – Memory Management in Java

    原文地址:http://www.journaldev.com/2856/java-jvm-memory-model-memory-management-in-java Understanding JV ...

  4. Oracle RAC客户端tnsnames.ora相关配置及测试

    1.Oracle RAC服务端/etc/hosts部分内容如下 2.查看服务端的local_listener和remote_listener参数 3.客户端tnsnames.ora配置参考 3.1 1 ...

  5. 有了jsRender,妈妈再也不用担心我用jq拼接DOM拼接的一团糟了、页面整齐了、其他伙伴读代码也不那么费劲了

    写在前面 说来也很巧, 下午再做一个页面,再普通不过的分页列表,我还是像往常一样,基于MVC环境下,我正常用PagedList.MVC AJAX做无刷新分页,这时候问题就来了,列表数据中有个轮播图用到 ...

  6. 如何将MyEclipse项目导入eclipse

    我们经常会在网上下载一些开源项目,或者从别的地方迁移一些项目进来,但经常会发现导入后各种报错.这是初学java肯定会遇到的问题,本文对一些常见的处理方案做一个总结.(本文将MyEclipse项目导入e ...

  7. 20个非常棒的jQuery倒计时脚本

    使用jQuery倒计时插件可能是最简单最好的方式添加动态和交互式倒数计时器到您的网站上.我相信你已经注意到了,例如倒计时功能运行网站,显示倒计时,直到一个大事件.当网站正在维护,告诉用户什么时候回来, ...

  8. EFCore执行Sql语句的方法:FromSql与ExecuteSqlCommand

    前言 在EFCore中执行Sql语句的方法为:FromSql与ExecuteSqlCommand:在EF6中的为SqlQuery与ExecuteSqlCommand,而FromSql和SqlQuery ...

  9. Web内置对象 跨页面传值

    内置对象: 1.QueryString - 地址栏数据拼接 get传值方式 格式:?key=value优点:简单好用,速度快,不消耗服务器内存. 缺点:只能传字符串,保密性不好,长度有限 Reques ...

  10. .NET正则表达式基础入门(一)

    字符组 正则表达式的字符组十分简单,就是列出你所想要匹配的字符.阅读本章前,建议先下载我于CSDN上传的示例代码,下载无需分数,下载链接. 1.普通字符组 普通字符组,列出所有你需要匹配的字符. 例如 ...