JUC系列之(三)原子变量
原子变量-CAS算法
1. i++的原子性问题
i++的计算原理:读 - 改 - 写
int temp = i;
i = i + 1;
将i++赋给其他变量的时候会将temp的值赋给其他变量,比如:
int i = 10;
i = i++; // 这里i的值就是10,i++的值实际上就是临时变量temp的值
i++的原子性问题实例
package com.atguigu.juc;
public class TestAtomicDemo {
public static void main(String[] args) {
AtomicDemo atomicDemo = new AtomicDemo();
for(int j = 0; j< 20 ;j++){
new Thread(atomicDemo).start();
}
}
}
class AtomicDemo implements Runnable{
private int i = 0;
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
System.out.println(i++);
}
}
分析过程如下
2. 原子变量
jdk1.5后java.util.concurrent.atomic包下提供了常用的原子变量
工作原理:
-
volatile保证内存可见性
-
CAS (Compare-And-Swap)算法保证数据的原子性
CAS算法是
硬件
对于并发操作共享数据的支持CAS包含了三个操作数:
内存值 V
预估值(旧值) A更新值(新值) B
当且仅当V == A时, 才将B的值更新到共享变量中。否则,将不做任何操作
CAS算法逻辑:读取内存值作为V,计算出新值B后在替换之前再次读取内存值作为预估值A,比较内存值V和预估值A,如果相等则进行替换(比较并替换这个步骤是原子操作)
CAS算法:无锁、非阻塞
1.读取内存值
2.比较并交换
CAS算法与同步锁的比较:
CAS算法效率要高于同步锁,因为替换失败时不会阻塞,会一直重复进行
用原子变量改写3.1中的示例,解决i++的原子性问题
package com.atguigu.juc;
import java.util.concurrent.atomic.AtomicInteger;
public class TestAtomicDemo {
public static void main(String[] args) {
AtomicDemo atomicDemo = new AtomicDemo();
for(int j = 0; j< 20 ;j++){
new Thread(atomicDemo).start();
}
}
}
class AtomicDemo implements Runnable{
// private volatile int i = 0;
private AtomicInteger i = new AtomicInteger(0);
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
System.out.println(i.getAndIncrement());
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术