高并发之 CAS的使用和底层原理

本文介绍了在多线程环境下,Java的Atomic原子操作类为何引入及其实现原理,通过CAS(Compare And Swap)无锁算法确保并发安全。Atomic类提供了比synchronized更好的性能,其底层由Unsafe类支持,Unsafe类提供了直接操作内存的能力,包括对象字段、数组、内存分配等。然而,CAS存在CPU开销大、不能保证代码块原子性和ABA问题等缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CAS

在了解CAS之前,我们要先要了解一下atomic(java.util.concurrent.atomic),为什么在jdk1.5开始引入了atomic包呢?

Atomic
1、为什么要使用Atomic类
在多线程和高并发环境中,我们经常会对一个int型的共享变量值进行+1或-1操作,例如:

int count = 0;
// ...
count ++;

但是这种写法,在多线程共同修改共享变量的情况下,会出现问题,导致实际值和预期值不符,即上面的代码是线程不安全的。因此我们需要实现线程的同步。通常的做法就是使用synchronized关键字修饰相关方法,或对代码块加锁。

package com.guigu.JMM;


import jdk.nashorn.internal.ir.CallNode;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author xff
 * @createTime 2022/5/3 18:32
 *
 * volatile 是虚拟机提供的轻量级的同步机制 -->可见性,不保证原子性,禁止指令重排
 *    低配版的synchronized
 * jmm 内存模型, -->可见性(线程副本的变量更改通知主内存,可做到线程通信)
 *                 原子性,(不可分割,完整性,某个线程在运行,不能被打扰,同时成功,同时失败)
 *                 有序性
 *
 *
 */

class MyDate{
 volatile int  number=0;  //初始值0 没有可见性 volatile   加了之后就可见了相当于锁syn....
    //使用guc 的atomicInteger 保证原子性的方法
    AtomicInteger atomicInteger =  new AtomicInteger();
    public void update(){
        this.number=60; //更新值的函数
    }

    public  void addPlusPlus(){ // 加了volatile关键字,验证不保证原子性
           //加了synchronized 锁,才能保证原子性 但是太重量级
        //那么如何解决呢?  使用guc 的atomicInteger
        number++;  //i++ 是三步做的操作
            //拿到值, 做操作,写入主内存
    }


    public void addMydateAtomic(){
        atomicInteger.getAndIncrement();
         //相当于 i++
    }

}

/**
 * 下面验证可见性 (number没有加volatile 关键字可见性修饰
 *     main  主线程
 *     aaa   线程
 *    刚开始共用 mydate 数据number aaa修改   主不可见
 *
 *  验证原子性 (添加了volatile)
 */
public class  Volatile {
    public static void main(String[] args) {  //主线程

         MyDate myDate = new MyDate();
         //开多个线程 进行 number的相加
        for (int i = 1; i <=20; i++) {
            new Thread(  //20个线程 ,一个线程调用 100次
                    () ->{
                        for (int j = 0; j < 1000; j++){
                            myDate.addPlusPlus();
                            myDate.addMydateAtomic();
                        }
                    },String.valueOf(i)).start();
               }

        //等待上面的线程执行完之后,主线程在做操作
        while (Thread.activeCount()>2){
             // 一个main,一个gc
            Thread.yield(); //线程让步
        }

        System.out.println(Thread.currentThread().getName()+ "  number "+myDate.number);
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是小晴晴呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值