什么是CAS?

概念:CAS是基于乐观锁思想的一种实现机制,主要是用来在不加锁的情况下,保证线程安  全的.

首先:先要了解一下什么是锁;

当多个线程同时对贡献资源进行操作时,会有线程安全的问题.可以通过加锁的方式来解决线程安全的问题  

加锁方式1:sychronized

Thread threadA = new Thread(() -> {
    synchronized (obj) {
        for (int i = 0; i < 100; i++) {
            System.out.println(i);//输出正数
            //notify() 唤醒正在当前锁对象等待的单个线程,如果有多个线程,则选择其中一个线程进行唤醒
            obj.notify();//唤醒等待的线程B
            try {
                obj.wait();//等待B输出完毕
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        obj.notify();//唤醒可能还在等待的线程B
    }
});

加锁方式2:lock锁

try {
    lock.lock();
    String name = Thread.currentThread().getName();
    if(this.money>=money){
        System.out.println(name+"来取钱"+money+"成功");
        this.money-=money;
        System.out.println(name+"来取钱后,余额剩余: "+this.money);
    }else {
        System.out.println(name+"取钱失败!余额不足.");
    }
} finally {
    lock.unlock();
}

乐观锁的思想:不加锁实现线程安全

CAS基于这个思想,对八大基本数据类型进行了一次包装:八大原子类,直接对原件进行操作,在多个线程同时对原子类变量进行操作时,每个线程先拿到一份变量的值存到自己线程的小内存中.,这里有一个细节,这个变量被关键字Volatile修饰,保障了线程的可见性.

每个线程在对变量操作时会先保存一份老值,在同步变量的新值时,先对比老值是否和原来一致,如果不一致就不对其进行同步.再次获取老值,对变量进行操作,底层就是一个while循环,直到满足老值与新值一致,跳出while循环.

好处:

极大的提高了效率,比加锁提高了三倍不至!它节省的就是cup沉睡和唤醒线程的效率.

坏处:

局限性极大,只有在对单个变量操作时适用.如果是很长的代码块.如果一直有一个线程占用共享变量

,那么其他线程将一直在死循环里,长时间的话会极大的降低效率.

CAS的底层并非Java代码实现的,CAS的底层是调用的C++的方法,而C++又是调用的汇编语言的函数,在这个汇编函数里有两条对原子操作的汇编指令其实加了lock锁.

CAS引发的aba问题:

假如有线程A,线程B两个线程.这时有一个变量C.

线程AB同时对C进行+1操作.

在线程A对变量C+1之后,这时如果cpu分配的时间片到了,线程B拿到锁进入对C进行+1,再-1.变量已经发生了一次变化, 线程A醒来,不会发现变量已经发生过一次改变,仍正常对其进行操作,有可能会引发不可名状的问题.这就是ABA问题.

给变量加上一个版本号即可解决这个问题.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值