CAS指令与MESI缓存一致性协议、 “轻量级锁” 与原子操作

本文详细介绍了CAS(Compare-And-Swap)指令在并行编程中的重要作用,及其在Intel CPU上的实现,如CMPXCHG指令。同时,文章探讨了MESI缓存一致性协议如何避免多CPU环境下缓存不一致的问题,以及这对并发性能的影响。通过源码分析,展示了Java中的compareAndSwapInt操作的实现原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CAS指令与MESI缓存一致性协议、 “轻量级锁” 与原子操作

“最轻量级的锁”,通常也叫”原子操作”,之所以加引号是因为他们在汇编级别并不是原子操作,是用多条指令完成的,这些操作大多都是利用CPU支持的汇编指令.

CAS(Compare-And-Swap)指令是并行程序设计最基础的基石。

CAS指令,在Intel CPU上称为CMPXCHG。最常见的原子操作有Compare and Exchange,Self Increase/Decrease等等

80486 CPU相关指令:

LOCK:这是一个指令前缀,在所对应的指令操作期间使此指令的目标操作数指定的存储区域锁定,以得到保护。

XADD:先交换两个操作数的值,再进行算术加法操作。多处理器安全,在80486及以上CPU中支持。

CMPXCHG:比较交换指令,第一操作数先和AL/AX/EAX比较,如果相等ZF置1,第二操作数赋给第一操作数,否则ZF清0,第一操作数赋给AL/AX/EAX。多处理器安全,在80486及以上CPU中支持。

XCHG:交换两个操作数,其中至少有一个是寄存器寻址.其他寄存器和标志位不受影响.

80486以上都支持这四个操作,因此当今几乎100%CPU都支持这两个指令

这一系列操作是原子的,不可能被中断。基本上所有的同步机制,与信号量、Java中的synchronized等的实现最终都要用到CAS指令,即使锁无关的数据结构也离不开CAS指令。

<think>我们首先来总结Java并发的知识框架,然后分别给出对应的详细知识。Java并发涉及多个层面,包括基本概念、线程基础、并发工具类、并发容器、线程池、原子类、机制、内存模型等。下面将按照这些模块进行详细阐述。 ### 一、Java并发知识框架 1. **线程基础** - 线程的创建启动 - 线程状态生命周期 - 线程的基本操作(sleep, yield, join, interrupt等) 2. **线程安全** - 什么是线程安全? - 原子性、可见性、有序性 - 实现线程安全的方式(同步代码块、同步方法、原子类等) 3. **机制** - synchronized关键字(原理、升级过程) - Lock接口及其实现(ReentrantLock, ReadWriteLock等) - 的分类(可重入、公平非公平、乐观悲观) 4. **并发工具类** - CountDownLatch - CyclicBarrier - Semaphore - Exchanger - Phaser 5. **并发容器** - ConcurrentHashMap - CopyOnWriteArrayList - BlockingQueue及其实现(ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue, DelayQueue) - ConcurrentSkipListMap和ConcurrentSkipListSet 6. **线程池** - Executor框架 - ThreadPoolExecutor(核心参数、工作原理、拒绝策略) - ScheduledThreadPoolExecutor - Executors工具类(提供的工厂方法及使用注意) 7. **原子类** - 基本类型(AtomicInteger, AtomicLong, AtomicBoolean) - 数组类型(AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray) - 引用类型(AtomicReference, AtomicStampedReference, AtomicMarkableReference) - 字段更新器(AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater) 8. **Java内存模型(JMM)** - 主内存工作内存 - 内存间交互操作(8种原子操作) - volatile关键字(原理、使用场景) - happens-before原则 - final关键字的内存语义 9. **其他高级主题** - Fork/Join框架 - CompletableFuture - ThreadLocal - 并发设计模式(如生产者-消费者、线程池模式等) ### 二、详细知识 由于篇幅限制,这里对每个模块选择部分核心内容进行详细说明。 #### 1. 线程基础 - **创建线程**:继承Thread类或实现Runnable接口(推荐),也可以使用Callable和Future。 - **线程状态**:NEW(新建)、RUNNABLE(可运行)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(定时等待)、TERMINATED(终止)。 - **线程操作**: - `sleep()`:当前线程休眠,不释放。 - `yield()`:提示调度器当前线程愿意让出CPU,但不保证。 - `join()`:等待该线程终止。 - `interrupt()`:中断线程,设置中断标志位,需要线程自己检查并处理。 #### 2. 线程安全 - **原子性**:一个操作不可中断,要么全部执行成功要么全部不执行。可通过synchronized、Lock、原子类保证。 - **可见性**:一个线程修改了共享变量,其他线程能够立即看到。可通过volatile、synchronized、Lock保证。 - **有序性**:程序执行的顺序按照代码的先后顺序执行(由于指令重排序,可能乱序)。可通过volatile、synchronized、Lock保证。 #### 3. 机制 - **synchronized**: - 修饰实例方法:是当前实例对象。 - 修饰静态方法:是当前类的Class对象。 - 修饰代码块:是括号里的对象。 - 升级:无 -> 偏向 -> 轻量级 -> 重量级(不可逆)。 - **ReentrantLock**: - 可重入、可中断、可设置公平(默认非公平)、支持多个条件变量(Condition)。 - 需要显式加,一般在finally块中解。 #### 4. 并发工具类 - **CountDownLatch**:一个或多个线程等待其他线程完成操作。初始化一个计数器,调用`countDown()`减1,调用`await()`阻塞直到计数器为0。 - **CyclicBarrier**:一组线程互相等待,到达一个屏障点再继续执行。可重复使用。 - **Semaphore**:控制同时访问特定资源的线程数量,通过许可证(permits)实现。 #### 5. 并发容器 - **ConcurrentHashMap**:线程安全的HashMap,Java7使用分段,Java8使用CAS+synchronized(住链表头节点)。 - **BlockingQueue**:阻塞队列,常用于生产者-消费者模型。例如,ArrayBlockingQueue有界,LinkedBlockingQueue可选有界/无界。 #### 6. 线程池 - **核心参数**: - corePoolSize:核心线程数。 - maximumPoolSize:最大线程数。 - keepAliveTime:非核心线程空闲存活时间。 - workQueue:任务队列(如ArrayBlockingQueue, LinkedBlockingQueue, SynchronousQueue)。 - threadFactory:线程工厂。 - handler:拒绝策略(AbortPolicy, CallerRunsPolicy, DiscardPolicy, DiscardOldestPolicy)。 - **工作流程**:提交任务 -> 核心线程未满则创建新线程执行;核心线程已满则放入队列;队列满则创建非核心线程执行;线程数达到最大且队列满则触发拒绝策略。 #### 7. 原子类 - 基于CAS(Compare And Swap)操作实现,底层调用Unsafe类的方法。 - 例如,`AtomicInteger`的`incrementAndGet()`方法通过循环CAS实现原子自增。 #### 8. Java内存模型(JMM) - **volatile**:保证可见性和禁止指令重排序(通过内存屏障实现),但不保证原子性。 - **happens-before原则**:包括程序次序规则、定规则、volatile规则、传递性等,用于判断数据是否存在竞争,线程是否安全。 #### 9. 其他 - **ThreadLocal**:每个线程有自己独立的变量副本,通过ThreadLocalMap实现,注意内存泄漏问题(使用后调用remove())。 - **Fork/Join**:将大任务拆分成小任务并行执行,再合并结果。使用工作窃取(work-stealing)算法。 ### 学习建议 1. 理解每个概念的基本原理和适用场景。 2. 动手实践,编写多线程程序,并尝试使用不同的并发工具。 3. 阅读源码,特别是java.util.concurrent包下的类。 4. 结合《Java并发编程实战》等书籍深入学习。 以上内容涵盖了Java并发的主要知识点,深入理解这些内容将有助于你在面试中应对并发相关的问题。 §§相关问题§§ 1. 请解释synchronized关键字的升级过程。 2. 什么是CAS操作?它有什么优缺点? 3. 线程池的四种拒绝策略分别是什么?各自的使用场景是什么? 4. volatile关键字如何保证可见性和有序性? 5. ConcurrentHashMap在Java7和Java8中的实现有何不同?</think>### Java并发知识框架详细总结 #### 一、并发核心知识框架 ```mermaid graph TD A[Java并发体系] --> B[线程基础] A --> C[线程安全] A --> D[机制] A --> E[JMM内存模型] A --> F[并发工具类] A --> G[并发容器] A --> H[线程池] A --> I[原子类] ``` #### 二、详细知识点分解 1. **线程基础** - 线程创建:`Thread`类、`Runnable`/`Callable`接口 - 线程状态:NEW/RUNNABLE/BLOCKED/WAITING/TIMED_WAITING/TERMINATED - 线程操作:`start()`, `join()`, `interrupt()`, `yield()` - 守护线程:`setDaemon(true)` 2. **线程安全三大特性** - 原子性:synchronized/Lock/原子类 - 可见性:`volatile`/synchronized/final - 有序性:`volatile`/synchronized/happens-before原则 3. **机制** - `synchronized`: - 对象头MarkWord结构(32/64位) - 升级:无→偏向轻量级→重量级 - 消除粗化 - `ReentrantLock`: - AQS(AbstractQueuedSynchronizer)实现原理 - 公平/非公平 - `Condition`条件变量 - 优化:自旋/适应性自旋 4. **JMM内存模型** - 主内存工作内存交互协议 - 内存屏障:LoadLoad/StoreStore/LoadStore/StoreLoad - happens-before八大原则 - `volatile`底层实现:Lock前缀指令+MESI缓存一致性协议 5. **并发工具类** - `CountDownLatch`:倒计数器 - `CyclicBarrier`:循环栅栏 - `Semaphore`:信号量 - `Exchanger`:线程数据交换 - `Phaser`:阶段器(JDK7+) 6. **并发容器** - `ConcurrentHashMap`:分段/CAS+synchronized - `CopyOnWriteArrayList`:写时复制 - 阻塞队列:`ArrayBlockingQueue`/`LinkedBlockingQueue`/`SynchronousQueue` - `ConcurrentSkipListMap`:跳表实现 7. **线程池体系** ```java // 核心参数 ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler ) ``` - 工作流程:核心线程→任务队列→非核心线程→拒绝策略 - 拒绝策略:AbortPolicy/CallerRunsPolicy/DiscardPolicy/DiscardOldestPolicy - `ForkJoinPool`:工作窃取算法 8. **原子类** - 基础类型:`AtomicInteger`/`AtomicLong` - 引用类型:`AtomicReference`/`AtomicStampedReference`(解决ABA问题) - 字段更新:`AtomicIntegerFieldUpdater` - 底层实现:CAS+自旋+Unsafe类 #### 三、底层原理重点 1. **AQS原理** - CLH队列(双向链表) - 状态变量`state` - 模板方法模式:`tryAcquire()`/`tryRelease()` 2. **CAS底层** - CPU原子指令:`cmpxchg`(x86架构) - 三大问题:ABA问题(版本号解决)、自旋时间长、只能保证单个变量原子性 3. **synchronized实现** - 对象监视器(Monitor):`_owner`/`_EntryList`/`_WaitSet` - 字节码指令:`monitorenter`/`monitorexit` 4. **线程通信机制** - `wait()`/`notify()`:对象监视器 - `Condition.await()`/`signal()`:AQS条件队列 #### 四、学习路线建议 1. 先掌握基础API使用 2. 深入阅读`java.util.concurrent`源码 3. 结合JOL工具分析对象头 4. 使用JConsole/VisualVM监控线程 5. 实践场景:生产者-消费者/读写/线程池任务调度
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI天才研究院

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值