CAS面试题

一:CAS是什么

比较并交换,它包含三个操作数—内存位置值、期望值与更新值,执行CAS操作的时候,内存位置值与期望值进行比较,如果相等,自动将该位置更新为新值

二:CAS为什么能保证原子性?

CAS是靠硬件实现的从而在硬件层面提升效率,最底层还是交给硬件来保证原子性,实现方式是基于硬件平台的汇编指令,在inter的CPU中,使用的是汇编指令compxchg指令
CAS面试题_第1张图片

三:谈谈对Unsafe类的理解?

Unsafe类是CAS的核心类,由于Java方法无法直接访问底层系统,需要通过本地(native)方法来访问,Unsafe相当于一个后门,基于该类可以直接操作特定内存的数据。Unsafe类中的所有方法都是native修饰的

四:我们知道i++是线程不安全的,那AtomicInteger.getAndIncrement()如何保证原子性?

AtomicInteger类主要利用CAS+volatile和native方法来保证原子操作,从而避免synchronized的高开销,执行效率大为提升。

五:自旋锁

CAS是实现自旋锁的基础,采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗CPU。

六:手写一个自旋锁

通过CAS完成自旋锁,A线程先进来调用myLock方法自己持有锁5秒钟,B随后进来后发现当前有线程持有锁,所以只能通过自旋等待,直到A释放锁后B随后抢到。

/**
 * @Author:xiaoqi
 * @creat 2023/8/9 22:28
 * 简易自旋锁实现
 */
public class SpinLockDemo {
    AtomicReference atomicReference = new AtomicReference<>();

    public void lock() {
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName() + "\t --------come in");
        while (!atomicReference.compareAndSet(null,thread)){

        }
}
public void unLock(){
    Thread thread = Thread.currentThread();
    atomicReference.compareAndSet(thread,null);
    System.out.println(Thread.currentThread().getName() + "\t --------task over,unLock.........");
}

public static void main(String[] args) {
    SpinLockDemo spinLockDemo = new SpinLockDemo();
    new Thread(() -> {
        spinLockDemo.lock();
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        spinLockDemo.unLock();
    }, "A").start();


    try {
        TimeUnit.MILLISECONDS.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    new Thread(() -> {
        spinLockDemo.lock();
        spinLockDemo.unLock();
    }, "B").start();
 }
}

七:ABA问题怎么产生的?

CAS算法实现一个重要前提需要提取出内存中某时刻的数据并在当下时刻比较并替换,那么在这个时间差类会导致数据的变化。

解决办法:版本号时间戳原子引用
在这里插入图片描述

你可能感兴趣的:(juc,java)