java原子操作(CAS)

在看了有关的CAS介绍之后,记录一下CAS的相关知识,作为再查阅。

java利用处理器的CAS(Compare And Swap)指令,循环执行数据比对,直到成功就停止循环。

实际过程:

如果多个线程要对一个变量A(Integer)进行修改,假设变量A初始化值为1,此时线程1要对A进行修改,修改过程,线程1通过传入期望值和修改值,与变量A的初始化值进行匹配。期望值与初始化值匹配成功就将A的值改为修改值;匹配失败就一直循环匹配,直到成功停止。

常用的CAS原子操作类:AtomicInteger,AtomicLong,AtomicReference(引用类型),AtomicIntegerArray/AtomicLongArray(数组类型);

JDK8:新增了:DoubleAccumulator、LongAccumulator、DoubleAdder、LongAdder

借用阿里巴巴的java规范中并发处理13项

LongAdder的具体信息读过一篇文章:

https://blog.csdn.net/f641385712/article/details/84934085

一个小示例:

package com.wuml.thread.cas;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author by wml on 2019/11/27.
 */
public class AtomicInt extends AtomicInteger{

    static AtomicInteger atomicInteger = new AtomicInteger(10);

    public static void main(String[] args) {

        // 直接获取值
        System.out.println(atomicInteger.get());
        // 先返回10 然后--> 9
        System.out.println(atomicInteger.getAndDecrement());
        // 先返回9 然后--> 10
        System.out.println(atomicInteger.getAndIncrement());
        // 先-->11 然后返回
        System.out.println(atomicInteger.incrementAndGet());

    }
}

经过网上的查阅:

CAS的问题大概归为3类:

1、ABA问题

如果另一个线程修改V值,假设原来是A,先修改成B后又修改回A,当前线程的CAS操作无法分辨V是否变化。

jdk中提供了2个版本号记录的类解决这个问题:

AtomicStampedReference(stamp修改了变量就增加)
AtomicMarkableReference(以布尔型确认是否修改变量)

2、只能保证一个共享变量的原子操作

3、开销问题,当CAS一直匹配不成功时,一直自旋进行CAS操作。

只要是谈及多个线程对同一个变量的访问,就会想到synchronized;

synchronized:是基于阻塞式的锁机制;被阻塞的线程优先级高,大量的线程竞争锁会消耗CPU,可能会出现死锁等情况。

synchronized是属于内置锁,当然会有显式锁,后面继续记录显式锁Lock与synchronized的区别与实践。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值