学过多线程就会接触到并发,并发再多线程中的重要性不言而喻,在Java中还有并发包,里面实现了各种各样的方法来帮助我们解决多线程带来的各种问题。而要想读懂这些底层问题,CAS是绕不过的知识,大多底层都是以CAS来实现的。今天就带大家来学习CAS相关的知识。
一、什么是CAS?
CAS: 全称Compare and swap,字面意思:" 比较并交换 "
一个CAS涉及到的操作数有:
- 内存值V
- 旧的预期值A
- 要修改的新值B
有了这三个操作数,在看看它的操作:
- 首先输入旧的预期值A 和修改后的新值 B
- 对比变量是旧值和内存值是否相同
- 如果相同,将旧值改为新值
这也就侧面的表现出了对于多个线程都对某个值进行修改时,保证了修改前拿到的值是期望值才会操作。
二、为什么要有CAS
还记得之前多线程的经典例子嘛,就是多个线程同时对一个共享变量进行修改值,最终修改后的值大概率不是正确的结果。也就是对于i ++ 操作,在多线程中是保证不了它的正确性。
原因呢,就是i ++ 本身并不是一个原子性的操作,它可以分成三步:
- 从主内存中读取到 i 的值
- 对 i 进行+1 操作
- 写回到主内存
这就导致多线程在执行该操作时,线程A、B可能同时从主内存中获得一个值后分别 +1 后写回到主内存。导致结果的错误,这时候你就会想到 那用 锁 呗! 所以解决的方式就是使用synchronized关键字来进行加锁。
的确,这种多线程导致的原子性问题可以加锁,使得众多线程竞争锁,拿到锁的线程才可以进行下一步的操作,其它线程则都开始阻塞,直到这个线程释放了锁后,唤醒其它线程,再次开始竞争锁。
但对于线程的阻塞和唤醒都是非常消耗时间的! 如果像i ++ 的操作,仅仅只是每次进行加一操作就要经历线程唤醒和重新竞争锁