当前位置:网站首页>【AtomicInteger】常规用法
【AtomicInteger】常规用法
2022-08-09 22:07:00 【程序员·小李】
众所周知,AtomicInteger用于多线程下线程安全的数据读写操作,避免使用锁同步,底层采用CAS实现,内部的存储值使用volatile修饰,因此多线程之间是修改可见的。
1. 构造
public AutomicInteger(int initValue): 有参构造,初始化为initValue
public AutomicInteger(): 无参构造,相当于AutomicInteger(0)
2. 自增1
public int getAndIncrement(): 返回当前值,并自增1
AtomicInteger ai = new AtomicInteger(5);
ai.getAndIncrement(); // 5
ai.get(); // 6
public int incrementAndGet(): 先自增1,再返回自增后的值
AtomicInteger ai = new AtomicInteger(5);
ai.incrementAndGet(); // 6
ai.get(); // 6
3. 自减1
public int getAndDecrement(): 返回当前值,并自减1
AtomicInteger ai = new AtomicInteger(5);
ai.getAndDecrement(); // 5
ai.get(); // 4
public int decrementAndGet(): 自减1, 返回自减后的值
AtomicInteger ai = new AtomicInteger(5);
ai.decrementAndGet(); // 4
ai.get(); // 4
4. 如果原来是A,则更新成B
public boolean compareAndSet(int source, int dest):source是改之前的值,Dest是改之后的值,source与当前真实值匹配了才能执行成功,返回值表示是否执行成功。
AtomicInteger ai = new AtomicInteger(10);
ai.compareAndSet(100, 12); // false, 因为改之前不是100
ai.get(); // 10
ai.compareAndSet(10, 12); // trueai.get(); // 12
5. 自增/自减N
public int getAndAdd(int delta): 先获取当前值,再进行计算val = val + delta
AtomicInteger ai = new AtomicInteger(10);
ai.getAndAdd(2); // 10ai.get(); // 12
public int addAndGet(int delta): 先计算 val = val + delta,再返回最新值
AtomicInteger ai = new AtomicInteger(10);
ai.addAndGet(2); // 12ai.get(); // 12
当然,这个方法也支持负数参数,也就意味着可以做减法
AtomicInteger ai = new AtomicInteger(5);
System.out.println(ai.addAndGet(-1)); // 46. 硬编码的二元计算逻辑
public int getAndUpdate (IntUnaryOperator opeartion): 使用lambda表达式进行二元运算,获取到的是旧值。
AtomicInteger ai = new AtomicInteger(10);
ai.getAndUpdate(x -> x + 2); // 10, oldVal
ai.get(); // 12
public int updateAndGet (IntUnaryOperator opeartion): 使用lambda表达式进行二元运算,获取到的是新值。
AtomicInteger ai = new AtomicInteger(10);
ai.updateAndGet(x -> x + 2); // 12, newVal
ai.get(); // 12
当然,这里支持减法也同样没问题
AtomicInteger ai = new AtomicInteger(5);
System.out.println(ai.updateAndGet(val -> val - 1)); // 47. 非硬编码的二元运算逻辑
public int getAndAccumulate(int factor, IntBinaryOperator operation): 先返回旧值,再进行计算
AtomicInteger ai = new AtomicInteger(10);
int result = ai.getAndAccumulate(5, new IntBinaryOperator() {@Override public int applyAsInt(int left, int right){ return left + right; } }); // result = 10, 旧值 ai.get(); // 15新值
public int accumulateAndGet(int factor, IntBinaryOperator operation): 先计算,再返回新值
AtomicInteger ai = new AtomicInteger(10);
int result = ai.accumulateAndGet(5, Integer::sum); // 15
ai.get(); // 15
同样,这个方法的自由度大大提高
int val = -1;
AtomicInteger ai = new AtomicInteger(5);
System.out.println(ai.accumulateAndGet(val, (a, b)-> b-a)); // -6
8. 直接赋值
public void set(int newVal): 直接更新为新值,区别于compareAndSet需要比对旧值。
9. 直接取值
public int get(): 取最新值
附:
底层的CAS是操作系统级别的实现:
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
自旋式乐观锁实现数值更新
public final int getAndAddInt(Object object, long valueOffset, int delta) {
int currentValue; do { currentValue= this.getIntVolatile(object, valueOffset); } while(!this.compareAndSwapInt(object, valueOffset, currentValue, currentValue + delta)); return currentValue; }
边栏推荐
- 少儿编程 电子学会图形化编程等级考试Scratch三级真题解析(判断题)2022年6月
- 你真的了解乐观锁和悲观锁吗?
- leetcode:320.列举单词的全部缩写
- xctf攻防世界 Web高手进阶区 shrine
- Transfer Learning & Kemin Initialization
- A. Common Prefixes
- Common commands and technical function modules of Metasploit
- R语言修改dataframe数据列的名称:使用dplyr包的rename函数修改列名、使用colnmaes函数修改列名、在数据筛选的时候重命名列名
- c:forEach varStatus属性
- OSS文件上传
猜你喜欢
随机推荐
Miscellaneous talk - the sorrow of programmers
leetcode:320.列举单词的全部缩写
ArrayList 和 LinkedList 区别
【LaTex】 Font “FandolSong-Regular“ does not contain requested(fontspec)Script “CJK“.如何抑制此种警告?
制定量化交易策略的基本步骤有哪些?
xctf攻防世界 Web高手进阶区 shrine
What is the stability of the quantitative trading interface system?
Tencent continues to wield the "big knife" to reduce costs and increase efficiency, and free catering benefits for outsourced employees have been cut
2022年中国第三方证券APP创新专题分析
p5.js实现的炫酷星体旋转动画
c:forEach varStatus属性
typedef和#define的花里胡哨的用法
UNI-APP_监听页面滚动h5监听页面滚动
C. Mere Array
setter与getter访问器属性——数据驱动显示
杂谈——程序员的悲哀
守护进程
leetcode 38. 外观数列
迅为瑞芯微RK3399开发板设置Buildroot文件系统测试MYSQL允许远程访问
How to insist to use procedural system?









