android 面试题 CAS

本文详细解析了比较和交换(CAS)指令在多线程环境中的作用,以及Java利用CAS实现原子操作的具体方式,包括AtomicInteger类的使用示例和源码分析。

首先弄清楚什么是cas:

在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令。 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。 这是作为单个原子操作完成的。 原子性保证新值基于最新信息计算; 如果该值在同一时间被另一个线程更新,则写入将失败。 操作结果必须说明是否进行替换; 这可以通过一个简单的布尔响应(这个变体通常称为比较和设置),或通过返回从内存位置读取的值来完成(摘自维基本科)

在jdk后引入了一个很重要的包 java.util.concurrent.atomic

在这个包下很多类比如:AtomicInteger AtomicLong等就是为了多线程操作变量,线看下例子

package thread;
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerDemo {
    public static void main(String[] args) {
        //主内存的值
        AtomicInteger atomicInteger = new AtomicInteger(5);
       boolean isUpdate =  atomicInteger.compareAndSet(5,2019);
       System.out.println("-->"+atomicInteger.get());
        System.out.println("isUpdate-->"+isUpdate);
    }
}

首先主内存中的值是5 比如有二个线程t1和t2,那么在t1,t2中的工作内存的值都是从主内存拷贝过去的,也就是说t1,t2中的值都是5 ,那么这个时候t1线程对其进行修改,修改成2019,这个时候t1工作内存就把这个值刷新到主内存,主内存判断这个期望的值和主内存的值一样,那么就修改主内存中的值 为2019

看下源码:

 /**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * @param expect the expected value
     * @param update the new value
     * @return {@code true} if successful. False return indicates that
     * the actual value was not equal to the expected value.
     */
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

我们可以看到

Atomically sets the value to the given updated value if the current value {@code ==} the expected value

这个解释,就是说如果这个当前期望的值和设置的atomic的值相等就更新新的值

 大厂都喜欢问底层实现原理,那么如果是面试肯定会问,它是怎么实现的?

package thread;
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerDemo {
    public static void main(String[] args) {
        //主内存的值
        AtomicInteger atomicInteger = new AtomicInteger(5);
        System.out.println("atomicInteger-->"+atomicInteger.getAndIncrement());
    }
}

点击getAndIncrement()方法进入到源码中,

/**
     * Atomically increments by one the current value.
     *
     * @return the previous value
     */
    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }

它三个参数分别是:

this:表示当前类

valueOffset: 内存偏移量(内存地址)

1:就是常量了

发现getAndIncrement()方法是由unsafe对象调用的,而unsafe对象的创建:

private static final Unsafe unsafe = Unsafe.getUnsafe();

进入Unsafe类后是调用了:

public final int getAndAddInt(java.lang.Object o, long l, int i) { /* compiled code */ }

Unsafe是CAS的核心类,由于Java方法无法访问底层系统,需要通过本地(native)方法来访问,Unsafe相当于一个后门,基于该类可以直接操作特定内存的数据,Unsafe类存在与com.misc包下,其内部方法操作可以像C的指针一样操作内存,因为Java中的CAS操作依赖于Unsafe类的方法

 

CAS的全称是Compare. And.  Swap 它是一条CPU并发原语,

CAS并发原语体现在Java语言当中的sun.misc.Unsafe类中的各个方法,调用CAS中的方法,JVM会帮助我们实现CAS的汇编指令,这是一个完整依赖硬件的功能,通过它实现了Java中的原子操作,

 

CAS缺点:

1:循环时间长,开销大  因为底层使用了do...while操作

2:只能保证一个共享变量的原子操作

3:引出ABA问题?

以下是一些可用于面试准备的 Android 系统相关面试题: 1. Android 中,App 启动时系统会创建一个 Application 对象,用来存储系统的一些信息,这儿的 Application 就是是单例模式的应用。可以通过 Context.getApplicationContext() 获取唯一的 Application 实例。同时给出单例模式代码示例: ```java class Singleton { private volatile static Singleton instance; private Singleton() { } public static Singleton getInstance() { //第一重判断 if (instance == null) { //锁定代码块 synchronized (Singleton.class) { //第二重判断 if (instance == null) { instance = new Singleton(); //创建单例实例 } } } return instance; } } ``` 此为经典的双检锁实现单例模式的代码 [^4]。 2. 多线程相关问题: - 假如只有一个 cpu,单核,多线程还有用吗?(美团) - sychronied 修饰普通方法和静态方法的区别?什么是可见性? - 锁分哪几类? - CAS 无锁编程的原理。(字节跳动) - ReentrantLock 的实现原理。 - AQS 原理 (小米 京东) - Synchronized 的原理以及与 ReentrantLock 的区别。(360) - Synchronized 在 JDK1.8 之后做了哪些优化 (京东) - Synchronized static 与非 static 锁的区别和范围(小米) - volatile 关键字干了什么?(什么叫指令重排) (字节跳动) - volatile 能否保证线程安全?在 DCL 上的作用是什么? - volatile 和 synchronize 有什么区别?(B站 小米 京东) - 两个线程用不同的对象,怎么样?(字节跳动) - 什么是守护线程?你是如何退出一个线程的? - sleep、wait、yield 的区别,wait 的线程如何唤醒它?(东方头条、字节跳动) - sleep 是可中断的么?(小米) - 实现非阻塞式生产者消费者(字节跳动) - 如何开启一个线程,开启大量线程会有什么问题,如何优化?(美团) - 线程生命周期。 - ThreadLocal 是什么? - AyncTask 的原理。 - AsyncTask 中的任务是串行的还是并行的? - 线程池管理线程原理。 - 线程池的相关参数,有哪些类型的线程池,线程池任务如何调度,任务队列只是先进先出的队列吗,任务有优先级怎么办,知道优先级反转吗? (美团) - 有三个线程 T1,T2,T3,怎么确保它们按顺序执行? - Android 中操作多线程的方式有哪些? - 怎样获取当前线程是否是主线程 (字节跳动) - HandlerThread 是什么? - 线程间如何通信? - RxJava 线程切换原理,RxJava1 和 RxJava2 的区别有哪些? [^5]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值