CAS与原子类基本了解

一、简介

CAS即Compare and Swap,它体现一种乐观锁思想,被称之为无锁并发
比如多个线程要对一个共享的整形变量执行+1操作

//需要不断尝试
while(true){
 int 旧值 = 共享变量;//比如拿到了当前值0,共享变量从主内存读到工作内存
 int 结果 = 旧值+1;//在旧值0的基础上增加1,结果是1
 /*
 这时候如果别的线程把共享变量改成了5,本线程的正确结果是1 就作废了,这时候
 compareAndSwap 返回false,重新尝试,直到:
 compareAndSwap 返回true,表示我本线程做修改的同时,别的线程没有干扰
 */
 if(compareAndSwap(旧值,结果)){
 //尝试将结果赋值给共享变量,与此同时把旧值与当前共享变量做比较,因为怕写入结果时有其它线程把共享变量
 //值改啦,所以拿上一次读到的值与共享变量当前的值做比较,如果两个一致,那结果可以成功写入到共享变量一     致,反之,其它线程把共享变量改啦,那么这一次操作就失败
    //成功,推出循环
 }
}

获取共享变量时,为了保证该变量的可见性,可能不是最新的,需要使用volatile修饰,结合CAS和volatile可以实现无锁,适用于竞争不激烈,多核CPU的场景下(不断尝试机制,需要利用CPU时间,如果CPU就一个CAS不从谈起,一个线程,其它线程在修改时,你想尝试也无CPU时间可用)

  • 因为没有使用synchronized,所以线程不会陷入阻塞,这是效率提升的因素之一
  • 但如果竞争激烈,可以想到重试必然频繁发生,反而效率会受影响
    CAS底层依赖于一个Unsafe来直接调用操作系统底层的CAS指令

二、乐观锁与悲观锁

CAS是基于乐观锁的思想:最乐观的估计,不怕别的线程来修改共享变量,就算改了也没关系,我吃亏点在重试呗
synchronized是基于悲观锁的思想:最悲观的估计,得防着其它线程来修改共享变量,我上了锁你们都别想改,我改完了解开锁,你们才有机会
juc (java.util.concurrent) 中提供了原子操作类,可以提供线程安全的操作,例如AtomicInteger,AtomicBoolean 等,他们底层就是采用CAS技术+volatile来实现

public class JMMTest {
    private static AtomicInteger atomicInteger = new AtomicInteger(0);
    public static void main(String[] args) throws InterruptedException {
        Thread t1= new Thread(()->{
             for(int i=0;i<5000;i++){
                 atomicInteger.getAndIncrement();//获取并且自增i++
             }
         });

        Thread t2=new Thread(()->{
            for(int i=0;i<5000;i++){
                atomicInteger.getAndDecrement();//获取并且自减i--
            }
        });

        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(atomicInteger);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值