AtomicInteger的addAndGet(int delta)与getAndAdd(int delta)有什么区别?
结论:区别仅在于返回的结果,修改的值是相同的,但是返回的值不同。
看一下源码注释
1 /**
2 * Atomically adds the given value to the current value.
3 *
4 * @param delta the value to add
5 * @return the updated value
6 */
7 public final int addAndGet(int delta) {
8 return unsafe.getAndAddInt(this, valueOffset, delta) + delta;
9 }
10
11 /**
12 * Atomically adds the given value to the current value.
13 *
14 * @param delta the value to add
15 * @return the previous value
16 */
17 public final int getAndAdd(int delta) {
18 return unsafe.getAndAddInt(this, valueOffset, delta);
19 }
注意看下划线,一个是更新后的值,一个是更新前的值
源码:(sun.misc.Unsafe#getAndAddInt)
1 public final int getAndAddInt(Object object, long offset, int update) {
2 int expect;
3 do {
4 expect = this.getIntVolatile(this, offset);
5 } while (!this.compareAndSwapInt(this, offset, expect, expect + update));
6
7 return expect;
8 }
传入的形参就不必解释了,对照上面的代码应该能看懂
第二行,期望值
第四行,取内存(堆)中的数据
第五行,首先肯定要执行cas,然后就是根据返回值决定是否要继续执行。
这里有必要解释cas的执行过程,如下
1 int compare_and_swap(int *mem_val, int expect, int update)
2 {
3 int old_val;
4 old_val = *mem_val;
5 if(old_val == expect) *mem_val = update;
6 return old_val;
7 }
主要就是第五行,如果内存中的值和传进来的期望值相同,那就把内存中的值赋值为要更新的值,然后返回内存值。
可能有人对参数坑位有疑惑,这个问题其实仔细思考就能猜到。
object + offset => 定位到内存中对象属性的值
这样,也就能和内存值关联上了
写个demo试试
1 import java.util.concurrent.atomic.AtomicInteger;
2
3 /**
4 * @author Alin
5 * @date 2020/7/26
6 */
7 public class TestAtomicInt {
8 static AtomicInteger count = new AtomicInteger(0);
9
10 public static void main(String[] args) {
11 //返回新值
12 System.out.println(count.addAndGet(20));
13 System.out.println("\tcur = " + count.get());
14 /**
15 * public final int getAndAddInt(Object this, long offset, int update) {
16 * int expect;
17 * do {
18 * expect = this.getIntVolatile(this, offset);
19 * } while(!this.compareAndSwapInt(this, offset, expect, expect + update));
20 *
21 * return expect;//返回旧值
22 * }
23 */
24 System.out.println(count.getAndAdd(2));
25 //返回当前值
26 System.out.println("\tcur = " + count.get());
27
28 }
29 }
结果
20
cur = 20
20
cur = 22
AtomicInteger的addAndGet(int delta)与getAndAdd(int delta)有什么区别?的更多相关文章
- C语言复杂声明-void (*signal(int sig, void (*handler)(int)))(int);
问题提出 请分析此声明:void (*signal(int sig, void (*handler)(int)))(int); 求解过程 在对上面的例子作分析之前,我们需要了解C语言的声明优先级,&l ...
- 编写Java应用程序。首先,定义描述学生的类——Student,包括学号(int)、 姓名(String)、年龄(int)等属性;二个方法:Student(int stuNo,String name,int age) 用于对对象的初始化,outPut()用于输出学生信息。其次,再定义一个主类—— TestClass,在主类的main方法中创建多个Student类的对象,使用这些对象来测 试Stud
package zuoye; public class student { int age; String name; int stuNO; void outPut() { System.out.pr ...
- const int * p 和 int const * p 和 int * const p 的区别
首先注意,const int * p 和int const *p 是一样的,并且不管是不是*p,即使const int i和int const i也是一样的,所以我们接下来只讨论int const * ...
- (int),Int32.Parse() 和 Convert.toInt32() 的区别
在 C# 中,(int),Int32.Parse() 和 Convert.toInt32() 三种方法有何区别? int 关键字表示一种整型,是32位的,它的 .NET Framework 类型为 S ...
- (int &)a 和(int)a
[cpp] view plain copy float a = 1.0f; cout < < (int)a < < endl; cout < < ...
- C++中int *p[4]和 int (*q)[4]的区别
这俩兄弟长得实在太像,以至于经常让人混淆.然而细心领会和甄别就会发现它们大有不同. 前者是指针数组,后者是指向数组的指针.更详细地说. 前: 指针数组;是一个元素全为指针的数组.后: 数组指针;可以直 ...
- int * const 与 const int * 的区别
type * const 与 const type * 是在C/C++编程中特别容易混淆的两个知识点,现在就以 int * const 和 const int * 为例来简略介绍一下这两者之间的区别. ...
- open_clientfd(char* hostname,int port)和open_listenfd(int port)
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h&g ...
- 如何理解这段代码:void (*signal (int sinno,void(*func)(int)))(int)
void (*signal (int sinno,void(*func)(int)))(int) 先来看void(*func)(int) 这里的意思是声明一个函数指针func,它的参数类型为int ...
随机推荐
- XJOI 夏令营501-511测试11 统计方案
小B写了一个程序,随机生成了n个正整数,分别是a[1]..a[n],他取出了其中一些数,并把它们乘起来之后模p,得到了余数c.但是没过多久,小B就忘记他选了哪些数,他想把所有可能的取数方案都找出来.你 ...
- leetcode144add-two-numbers
题目描述 给定两个代表非负数的链表,数字在链表中是反向存储的(链表头结点处的数字是个位数,第二个结点上的数字是十位数...),求这个两个数的和,结果也用链表表示. 输入:(2 -> 4 -> ...
- 随笔1.流程控制--if
# 流程控制--if `-*- coding:utf-8 -*- #定义字符编码`## 1.判断条件if```python age = input("输入年龄:") #将交互式输入 ...
- 限制页面只能由微信内置浏览器打开,在其他浏览器打开跳转到Oauth2页面
在需要限制的页面加上 appid必填,可以获取也可以自己随意 <script> var ua = navigator.userAgent.toLowerCase(); var isWei ...
- VMware虚拟机 - 如何让鼠标从虚拟机中返回到个人计算机中
最简单的方式 按快捷键:ctrl+alt即可 彻底解决问题的方法:安装VMware Tools 前提条件 开启虚拟机 确认客户机操作系统正在运行 因为 VMware Tools 安装程序是使用 Per ...
- Zabbix实现电话告警通知的配置方法分享
如果要讨论下当下热门的监控系统,我想zabbix应该能够占有自己的一席之地,拥有不小的话语权吧.然而身为一名苦逼的运维,为了不错过重大的告警信息,就需要配置个[电话告警]来进行最快速的通知. zabb ...
- c++函数声明的位置对函数重载的影响
c++为了兼容c,也是采用(假)单遍编译.这特别影响函数重载决议(当c++编译器读到一个函数调用语句时,它必须从目前已看到的同名函数中选出最佳函数,哪怕后面的代码中出现了更合适的匹配) 1 #incl ...
- linux的别名(alias/unalias)
linux中有别名时先找的别名后找命令文件 临时创建是直接用alias. [root@localhost ~]# alias ls=pwd [root@localhost ~]# ls /root 其 ...
- 莫小安 Linux下Redis的安装与配置
转载自--Linux下Redis的安装与配置 redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcached类似,但很大程度补偿了 memcached的不足,它 ...
- webug第四关:告诉你了flang是5位数
第四关:告诉你了flang是5位数 开始看到有点懵 于是不要脸的看源码 burp跑弱口令