MST

星途 面试题库

面试题:Java中CAS操作的基本原理是什么,请简要阐述并说明其在多线程环境中的应用场景

请解释Java中CAS(Compare - and - Swap)操作的基本工作原理,例如涉及哪些核心操作数。并举例说明在多线程编程场景下,CAS操作可以解决什么样的并发问题,比如在计数器实现、锁机制等方面。
18.3万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

1. CAS基本工作原理

CAS 是一种乐观锁策略,其核心涉及三个操作数:

  • 内存位置(V):要更新的内存值。
  • 预期原值(A):在执行操作前,对内存位置 V 预期的值。
  • 新值(B):如果内存位置 V 的实际值与预期原值 A 相匹配,就将内存位置 V 的值更新为新值 B。

CAS 操作过程如下:首先读取内存位置 V 的实际值,将其与预期原值 A 比较,如果二者相等,意味着在读取 V 之后没有其他线程修改过 V 的值,此时将 V 的值更新为新值 B;如果不相等,则说明其他线程已经修改了 V 的值,当前操作失败,通常需要重试操作,直到成功。

2. 多线程编程场景下解决的并发问题

计数器实现

在多线程环境下实现计数器时,如果使用传统的变量自增操作(如 count++),由于其不是原子操作,多个线程同时执行会导致数据不一致问题。例如:

class Counter {
    private int count = 0;
    public void increment() {
        count++;
    }
    public int getCount() {
        return count;
    }
}

当多个线程同时调用 increment 方法时,可能会出现计数不准确的情况。

使用 CAS 实现线程安全的计数器:

import java.util.concurrent.atomic.AtomicInteger;

class CASCounter {
    private AtomicInteger count = new AtomicInteger(0);
    public void increment() {
        while (true) {
            int current = count.get();
            boolean success = count.compareAndSet(current, current + 1);
            if (success) {
                break;
            }
        }
    }
    public int getCount() {
        return count.get();
    }
}

这里 AtomicInteger 类内部使用 CAS 操作来实现原子的自增,保证了多线程环境下计数器的正确性。

锁机制

在实现锁机制方面,CAS 可以用于构建无锁数据结构。例如,使用 CAS 实现简单的自旋锁:

class SpinLock {
    private AtomicBoolean locked = new AtomicBoolean(false);
    public void lock() {
        while (true) {
            boolean expected = false;
            boolean success = locked.compareAndSet(expected, true);
            if (success) {
                return;
            }
        }
    }
    public void unlock() {
        locked.set(false);
    }
}

线程在获取锁时,通过 CAS 操作尝试将 lockedfalse 设置为 true,如果成功则获取到锁;如果失败则不断重试(自旋),直到获取到锁。解锁时只需将 locked 设置为 false。这样通过 CAS 操作避免了传统锁机制中可能出现的死锁等问题,并且在高并发且锁竞争不激烈的场景下,性能优于传统锁。