并发编程面试文章地址链接
内容 | 博客链接 |
---|---|
并发编程面试题之常见面试题 | https://blog.csdn.net/weixin_38251871/article/details/104658674 |
并发编程面试题之 volatile 关键字 |
https://blog.csdn.net/weixin_38251871/article/details/104667384 |
并发编程面试题之 CAS |
https://blog.csdn.net/weixin_38251871/article/details/104667406 |
并发编程面试题之锁 | https://blog.csdn.net/weixin_38251871/article/details/104667392 |
并发编程面试题之阻塞队列 | 待完成… |
并发编程面试题之 AQS |
待完成… |
并发编程面试题之线程池 | 待完成… |
并发编程面试题之 synchronized 和 ReentrantLock 的区别 |
https://blog.csdn.net/weixin_38251871/article/details/104667532 |
并发编程面试题之 CyclicBarrier、CountDownLatch、Semaphore |
待完成… |
并发编程面试题之 ConcurrentHashMap |
https://blog.csdn.net/weixin_38251871/article/details/104667433 |
并发编程面试题之 synchronized 实现原理 |
https://blog.csdn.net/weixin_38251871/article/details/104667415 |
什么是 CAS
在 Java
中的 Compare And Swap/Set
即 CAS
,当多个线程尝试使用 CAS 同时更新同一个变量的时候,只有其中一个线程能更新变量的值,而其他的线程都会失败,失败的线程并不会立即被挂起,而是被告知这次竞争中失败,并可以再次尝试。CAS 的算法过程:
它包含 3 个参数 CAS(V, E, N)
: V 表示要更新的变量(内存值)、E 表示预期值(旧值)、N 表示新值。当 V 值等于 E 值的时候, 把 V 的值设置为 N 值,如果 V 值和 E 值不相等,说明已经有其他线程做了更新,则当前线程什么都不做。最后 CAS
才返回当前的内存值 (V)
CAS 带来的问题
ABA 问题
CAS
会导致ABA 问题
, CAS 算法实现一个重要的前提是需要取出内存中某个时刻的值,而在下一个时刻进行比较和替换,那么在中间这个时间差可能会导致数据的变化- 例如:线程 A 从内存位置 V 中取出 A,这个时候另一个线程 B 也从内存中取出 A,并且线程 B 进行了一些操作变成 B, 然后线程 B 又将 V 位置的数据变成 A;这时候线程 A 进行 CAS 操作发现内存中的数据仍然是 A, 然后线程 A 操作成功。尽管线程 A 进行 CAS 操作成功,但是并不代表这个操作的过程是没有问题的
- 部分的乐观锁实现是通过版本号(
Version
)的方式来解决ABA 问题
, 乐观锁每次在执行数据修改操作时,都会带上一个版本号,一旦版本号和数据的版本号一致就可以执行修改操作并对版本号执行 +1 操作,否则就执行失败。因为每次操作的版本号都会随之增加,所以不会出现ABA 问题
,因为版本号只会增加不会减少 - 在
JDK 1.5
开始 JDK 的 atomic 包里提供了一个类AtomicStampedReference
来解决ABA 问题
不能保证代码块的原子性
CAS
机制所保证的只是一个变量的原子操作,而不能保证整个代码块的原子性【例:需要保证 3 个变量共同进行原子性的判断, 在这个时候就需要使用 synchronized 来操作】
CAS 造成 CPU 的利用率增加
- 在
CAS
里面是一个循环的过程,如果线程一直无法执行,CPU
资源就会一直被占用,造成CPU
的资源浪费