当前位置:网站首页>多线程04--线程的原子性、CAS
多线程04--线程的原子性、CAS
2022-07-22 10:44:00 【fengxianaa】
上一篇:多线程04--线程的有序性_fengxianaa的博客-CSDN博客
程序的原子性指整个程序中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节,有着“同生共死”的感觉。对线程而言,一个操作一旦开始,就不会被其他线程所干扰。
java中必须借助于synchronized、Lock、锁等,来保证整块代码的原子性
/**
* volatile不能保证原子性
*/
class Demo2 implements Runnable {
volatile int a = 0;
@Override
public void run() {
for(int i =0;i<10000;i++){
a++;
}
}
}
public class T04_Volatile {
public static void main(String[] args) throws InterruptedException {
Demo2 d = new Demo2();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();t2.start();
t1.join();t2.join();
System.out.println(d.a);
}
}
3. CAS
/**
* CAS: 全称 Compare And Set
* 过程:1. 先获取最新值a,
* 2. 进行CAS操作,操作时先判断值是否还是a,如果是就设置新值,如果不是,一直重复整个过程,称之为:自旋,
* 整个cas操作是CPU原语级,不可被打断,所以是原子性的
*
*
* 缺点:如果有大量的线程同时并发修改一个变量,那么可能会有很多线程会不停的自旋,这样性能就不好
*/
class Demo implements Runnable {
AtomicInteger a = new AtomicInteger(0);
@Override
public void run() {
for(int i =0;i<10000;i++){
a.incrementAndGet();
}
}
}
public class T01_Cas {
public static void main(String[] args) throws InterruptedException {
Demo d = new Demo();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();t2.start();
t1.join();t2.join();
System.out.println(d.a);
}
}
流程图
LongAdder
/**
* LongAdder,使用分段CAS以及自动分段迁移,提高并发性,最后计算出各个段的和值
* 底层原理:
* 1. 首先有一个base值,刚开始多线程来不停的累加数值,都是对base进行累加的,这时候跟AtomicInteger没有区别
* 2. 如果线程数量过多,就会开始施行分段机制,内部会搞一个Cell数组,每个元素是一个数值分段。
* 这时,让大量的线程分别去对不同Cell内部的value值进行CAS累加操作,这样就把CAS计算压力分散到了Cell数组的各个元素,提高效率
*
* 3. 内部实现了自动分段迁移的机制,也就是如果某个Cell的value执行CAS失败了,那么就会自动去找另外一个Cell分段内的value值进行CAS操作,
* 这样也解决了线程空旋转、自旋不停等待执行CAS操作的问题
*
* 4. 最后,如果你要从LongAdder中获取当前累加的总值,就会把base值和所有Cell分段数值加起来返回给你
*/
class Demo2 implements Runnable {
LongAdder a = new LongAdder();
@Override
public void run() {
for(int i =0;i<10000;i++){
a.increment();
}
}
}
public class T02_LongAdder{
public static void main(String[] args) throws InterruptedException {
Demo2 d = new Demo2();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();t2.start();
t1.join();t2.join();
System.out.println(d.a);
}
}
流程图
ABA问题:
int a =1;
1. 线程1 获取a的最新值后,准备CAS操作,但这时线程暂停
2. 线程2 修改a的值为2
3. 线程3 又修改a的值为1
4. 线程1 继续运行,修改a的值。
这种情况下,线程1 虽然可以修改成功,但是这个a已经不是最初的a了,中间经历了一些变化,可能含义不同了,如果修改成功,可能导致一些问题,这就是ABA问题。
解决:加时间戳或版本号
边栏推荐
猜你喜欢
【FPGA】:ip核--Divider(除法器)
Lingo 基本使用
进程fork
面试官:生成订单30分钟未支付,则自动取消,该怎么实现?
pytorch 动态调整学习率,学习率自动下降,根据loss下降
Binary search (recursive function)
【keil软件】仿真时如何使用逻辑分析仪查看波形
JSON output to file line by line in format
Pytorch dynamically adjusts the learning rate, and the learning rate automatically decreases according to loss
模拟学生信息输入界面
随机推荐
Wiring ability of twisted common centroid capacitor array under signal coupling constraints
1080 graduate admission (30 points)
YOLO v1、v2、v3
Highly configurable and scalable spiral capacitor design for high-density or high-precision applications
C language unsigned int and int
[literature reading and thought notes 14] beyond a Gaussian noise: residual learning of deep CNN for image recognition
【FPGA】:频率测量
【FPGA】:aurora核的使用
Jmeter性能测试
【FPGA】:MicroBlaze的使用
【面试:基础篇04:插入排序】
有源和无源设备的共质心布局:回顾和未来之路
电荷分级DAC中二元加权电容器的寄生感知大小和详细路由
Leetcode high frequency question: what is the difference between the combat effectiveness of the two soldiers with the closest combat effectiveness of N soldiers in the challenge arena
Pytorch dynamically adjusts the learning rate, and the learning rate automatically decreases according to loss
具有任意电容比的共质心电容阵列的自动生成
测试相关基础概念
1087 all roads lead to Rome (30 points)
具有非矩形布局1结构的电流镜的梯度灵敏度降低
基于非线性最坏情况分析的电荷缩放 DAC 中电容器的新棋盘放置和尺寸调整方法