当前位置:网站首页>面试题(CAS)
面试题(CAS)
2022-07-07 05:07:00 【一生酷到底】
常见大厂面试题准备
谈一谈对CAS的理解?
题目难度: 中等
题目描述: 提问线路CAS—> Unsafe—> CAS底层原理 —> 原子引用更新 —> 如何规避ABA问题
题目分析
compareAndSet怎么用?(比较并交换)
/** * boolean compareAndSet(int expect,int update) * - 如果主内存的值=期待值expect,就将主内存值改为update * - 该方法可以检测线程a的操作变量X没有被其他线程修改过 * - 保证了线程安全 */
public static void main(String[] args)
{
AtomicInteger atomicInteger = new AtomicInteger(5);
System.out.println(atomicInteger.compareAndSet(5, 10)+ "\t" + atomicInteger);
System.out.println(atomicInteger.compareAndSet(5, 20)+ "\t" + atomicInteger);
//true 10
//false 10
}
CAS底层原理简述?
1.Compare-And-Swap。是一条CPU并发原语。(原语:操作系统范畴,依赖硬件,不被中断。)
2.功能是判断内存某个位置的值是否为预期值(Compare),是就更新(Swap),这个过程是原子的。
3.功能描述
a:功能是判断内存某个位置的值是否为预期值(Compare),是就更新(Swap),这个过程是原子的。
b:cas有三个操作数,内存值V,旧预期值A,要更新的值B。仅当预期值A=内存值V时,才将内存值V修改为B,否则什么都不做
4.自旋:比较并交换,直到比较成功
5.底层靠Unsafe类保证原子性。
6.getAndIncrement() 源码解析(用了cas保证线程安全)
/** * 参数说明: * this: atomicInteger对象 * valueOffset:对象的内存地址 * unsafe:sun.misc.Unsafe类 * AtomicInteger中变量value使用volatile修饰,保证内存可见。 * 结论:底层依赖CAS操作/Unsafe类 * */
public final int getAndIncrement() {
return unsafe.getAndAddInt(this,valueOffset, 1);
}
/** 1. compareAndSwapInt:即CAS 2. while: 如果修改失败,会一直尝试修改,直到成功。 */
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 =this.getIntVolatile(var1, var2);
}
while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
简述:
- 调用了Unsafe类的getAndAddInt
- getAndAddInt使用cas一直循环尝试修改主内存
对Unsafe的理解?
- 该类所有方法都是native修饰,直接调用底层资源。sun.misc包中
- 可以像C的指针一样直接操作内存。java的CAS操作依赖Unsafe类的方法
CAS有哪些缺点?
- 循环时间长,开销大(如果cas失败,就一直do while尝试。如果长时间不成功,可能给CPU带来很大开销)
- 只能保证一个共享变量的原子操作(如果时多个共享变量,cas无法保证原子性,只能加锁,锁住代码段)
- 存在ABA问题
简述ABA问题和解决方案?
ABA问题描述: 线程1做CAS操作将A改为B再改为A,而线程2再做CAS时修改成功了,这不符合设计思想。
怎么解决:AtomicStampReference时间戳原子引用
ABA问题描述:
比如线程1从内存位置V中取出A,此时线程2也取出A。且线程2做了一次cas将值改为了B,然后又做了一次cas将值改回了A。此时线程1做cas发现内存中还是A,则线程1操作成功。这个时候实际上A值已经被其他线程改变过,这与设计思想是不符合的
这个过程问题出在哪?
如果只在乎结果,ABA不介意B的存在,没什么问题
如果B的存在会造成影响,需要通过AtomicStampReference,加时间戳解决。
原子更新引用是啥?
AtomicStampReference,使用时间戳,解决cas中出现的ABA问题。
/** * 如果希望原子操作的变量是 User,Book,此时需要使用AtomicReference类 */
public static void main(String[] args) {
User z3 = new User("z3",18);
User l4 = new User("l4",19);
AtomicReference<User> atomicReference = new AtomicReference<>(z3);
System.out.println(atomicReference.compareAndSet(z3, l4) + "\t" + atomicReference.get().toString());
System.out.println(atomicReference.compareAndSet(z3, l4) + "\t"+ atomicReference.get().toString());
//true [email protected]
//false [email protected]
}
AtomicReference存在ABA问题代码验证
AtomicReference atomicReference = new AtomicReference<Integer>(100);
/** * ABA问题验证: * 1--ABA * 2--A,C * @param args */
public static void main(String[] args) {
ABADemo abaDemo = new ABADemo();
new Thread(()->{
abaDemo.atomicReference.compareAndSet(100,101);
abaDemo.atomicReference.compareAndSet(101,100);
},"1").start();
new Thread(()->{
// 睡1s等线程1执行完ABA
try
{
TimeUnit.SECONDS.sleep(1);}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(abaDemo.atomicReference.compareAndSet(100,2020)+"\t"+abaDemo.atomicReference.get());
//true 2020
},"2").start();
AtomicStampReference解决ABA问题代码验证
解决思路:每次变量更新的时候,把变量的版本号加一,这样只要变量被某一个线程修改过,该变量版本号就会发生递增操作,从而解决了ABA变化
AtomicStampedReference atomicStampedReference = new AtomicStampedReference<Integer>(100,1);
public static void main(String[] args) {
// ABAProblem();
ABADemo abaDemo = new ABADemo();
new Thread(()->{
// 等线程2读到初始版本号的值
try
{
TimeUnit.SECONDS.sleep(1);}
catch (InterruptedException e) {
e.printStackTrace();}
System.out.println("线程1在ABA前的版本号:"+abaDemo.atomicStampedReference.getStamp());
abaDemo.atomicStampedReference.compareAndSet(100,101,abaDemo.atomicStampedReference.getStamp(),
abaDemo.atomicStampedReference.getStamp()+1);
abaDemo.atomicStampedReference.
compareAndSet(101,100,abaDemo.atomicStampedReference.getStamp(),abaDemo.atomicStampedReference.getStamp()+1);
System.out.println("线程1在ABA后的版本号:"+abaDemo.atomicStampedReference.getStamp());
},"1").start();
new Thread(()->{
// 存一下修改前的版本号
int stamp = abaDemo.atomicStampedReference.getStamp();
System.out.println("线程2在修改操作前的版本号:"+stamp);
// 睡1s等线程1执行完ABA
try
{
TimeUnit.SECONDS.sleep(2);}
catch (InterruptedException e) {
e.printStackTrace();}
System.out.println(abaDemo.atomicStampedReference.compareAndSet(100,2020,stamp,abaDemo.atomicStampedReference.getStamp()+1)+"\t" +abaDemo.atomicStampedReference.getReference());
//线程2在修改操作前的版本号:1
//线程1在ABA前的版本号:1
//线程1在ABA后的版本号:3
//false 100
},"2").start();
边栏推荐
- Open source ecosystem | create a vibrant open source community and jointly build a new open source ecosystem!
- Codeforce c.strange test and acwing
- Linux server development, detailed explanation of redis related commands and their principles
- Numbers that appear only once
- Who has docker to install MySQL locally?
- Qt学习27 应用程序中的主窗口
- Linux server development, MySQL process control statement
- 2022 welder (elementary) judgment questions and online simulation examination
- 2022 simulated examination question bank and online simulated examination of tea master (primary) examination questions
- 这5个摸鱼神器太火了!程序员:知道了快删!
猜你喜欢
2022 National latest fire-fighting facility operator (primary fire-fighting facility operator) simulation questions and answers
追风赶月莫停留,平芜尽处是春山
[quick start of Digital IC Verification] 15. Basic syntax of SystemVerilog learning 2 (operators, type conversion, loops, task/function... Including practical exercises)
Jmeter 的使用
调用 pytorch API完成线性回归
2022制冷与空调设备运行操作复训题库及答案
2022 welder (elementary) judgment questions and online simulation examination
padavan手动安装php
mysql多列索引(组合索引)特点和使用场景
Explore dry goods! Apifox construction ideas
随机推荐
复杂网络建模(三)
ROS Bridge 笔记(05)— carla_ackermann_control 功能包(将Ackermann messages 转化为 CarlaEgoVehicleControl 消息)
Force buckle 144 Preorder traversal of binary tree
Linux server development, MySQL stored procedures, functions and triggers
C语言二叉树与建堆
王爽 《汇编语言》之寄存器
Figure out the working principle of gpt3
快解析内网穿透助力外贸管理行业应对多种挑战
Linux Installation MySQL 8.0 configuration
mysql多列索引(组合索引)特点和使用场景
Introduction to basic components of wechat applet
青龙面板--整理能用脚本
Es FAQ summary
Niu Mei's mathematical problem --- combinatorial number
Find the mode in the binary search tree (use medium order traversal as an ordered array)
Implementation of replacement function of shell script
2022 tea master (intermediate) examination questions and mock examination
Binary tree and heap building in C language
MySQL multi column index (composite index) features and usage scenarios
Thinkcmf6.0 installation tutorial