JAVA并发编程-CAS设计及Atomic原子操作

原子性

        什么是原子性,比如事务的一大特征就是原子性,即要么全部执行、要么都不执行。

        在JAVA中,如线程A、线程B 同时执行一个代码块,我们常用Synchroized或者其他形式锁来保证同一时刻只有一个线程执行。这就是我们常用的锁机制,锁机制是一种颗粒度大、比较粗糙的机制。对于计数器这样的我们在用锁 岂不是 牛刀杀小鸡了,这里JAVA就提供了Atomic原子操作类。 原子操作类是基于CAS机制的。

什么是CAS?

CAS(Compare And Swap,比较并交换)是一种重要的并发控制机制,广泛应用于多线程编程中实现无锁(lock-free)算法。

CAS是一种原子操作,包含三个操作数:

  1. 主内存中存放的共享变量的值:V(一般情况下这个V是内存的地址值,通过这个地址可以获得内存中的值)。

  2. 工作内存中共享变量的副本值,也叫预期值:A。

  3. 需要将共享变量更新到的最新值:B。

操作逻辑:

1、读取旧值:线程读取内存位置 V 的当前值 A。
2、比较旧值:将读取的值 A 与预期的旧值进行比较。
3、交换值:如果当前值与预期值相同,则用新值 B 替换当前值。这个替换操作是原子的,即要么完全完成,要么完全不发生。
4、返回结果:如果替换成功,则返回 true 或成功信号;否则返回 false 或失败信号,表示旧值已被其他线程更改。

CAS操作通过一条CPU的原子指令(如cmpxchg指令)实现,保证了比较和更新的原子性。在执行CAS操作时,CPU会判断当前系统是否为多核系统,如果是,则会给总线加锁,确保只有一个线程能够执行CAS操作。这种独占式的原子性实现方式,比起使用synchronized等重量级锁,具有更短的排他时间,因此在多线程情况下性能更佳。

CAS问题

 ABA问题,通过增加版本号控制

 自旋耗时,设置自旋次数控制

只能保证一个共享变量,把多个共享变量封装成一个共享变量

Atomic原子操作

        JAVA提供了一套atomic原子操作类

并发安全相关问题

1.什么是线程安全

线程安全是多线程编程中的核心概念,指的是当多个线程同时访问某个类、对象或方法时,这个类、对象或方法仍然能够保持正确的行为,不需要额外的同步措施。

2.如何保证线程安全

        1.线程封闭

                我们把对象封装在当前线程内部,只有当前线程能看到此对象。

        2.栈封闭

                就是使用局部变量,局部变量会被拷贝到当前线程栈中,不共享。

        3.ThreadLocal

                使用ThreadLocal对线程进行封闭,记得合理remove(),ThreadLocal存在内存泄漏问题。

        4.使用无状态类

                没有成员变量的类叫做无状态类

        5.类不可变

                所有成员方法都加上final关键字

        6.加锁或CAS

死锁

        学术概念:

死锁是多线程编程中最棘手的问题之一,指两个或多个线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉,这些线程都无法继续执行下去。

死锁产生的四个必要条件(Coffman条件)

  1. 互斥条件:资源一次只能由一个线程占用

  2. 占有且等待:线程持有至少一个资源,并等待获取其他被占用的资源

  3. 不可抢占条件:已分配给线程的资源,不能被其他线程强行夺取

  4. 循环等待条件:多个线程形成头尾相接的循环等待资源关系

        理解概念:

        多个操作者(M>=2)争夺多个资源(N>=2)

        操作顺序不一致

        拿到资源不放手

排查死锁

        使用jstack分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值