Java CAS和AQS的实现原理

news/2024/11/17 23:29:11/

CAS

CAS(Compare And Swap)是一种并发控制机制,用于解决多线程并发访问共享资源时的数据一致性问题。

在Java中,CAS操作通常使用Atomic类来实现。例如,可以使用java.util.concurrent.atomic.AtomicInteger类来实现对整数类型的原子操作。Atomic类提供了一系列的原子操作方法,例如getAndAdd、getAndSet、compareAndSet等,可以用于实现CAS操作。

    /**
     * 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);
    }

这些CAS原子操作实际上都是Unsafe类提供的一系列native方法。

public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

CAS操作包括三个参数:内存位置V、旧的预期值A和新的值B。当且仅当内存位置V的值等于预期值A时,CAS操作才会将内存位置V的值更新为新的值B,否则不会进行任何操作。CAS操作是原子性的,因此可以保证多线程并发访问共享资源时的数据一致性。

CAS操作虽然可以保证数据的一致性,但是在高并发场景下,可能会出现ABA问题。ABA问题是指,在CAS操作中,如果内存位置V的值在操作过程中被修改了两次,且第一次修改后又被修改回原来的值,那么CAS操作会误认为内存位置V的值没有被修改过,从而导致数据的不一致性。为了解决ABA问题,可以使用版本号机制,即在每次修改内存位置V的值时,都将版本号加1,从而避免出现ABA问题。

AQS

AQS(AbstractQueuedSynchronizer)是Java中用于实现同步器的基础框架,例如ReentrantLock、Semaphore、CountDownLatch等。AQS的核心思想是使用一个FIFO的等待队列来管理线程的竞争和等待,从而实现同步器的功能。使用volatile保证可见性,使用CAS保证原子性。

AQS的实现原理可以简单地概括为以下几个步骤:

1. 定义一个内部类Node,用于表示等待队列中的节点。每个节点包含一个线程引用和一个状态值,用于表示线程的状态(例如等待、唤醒、取消等)。

2. 定义一个volatile类型的int变量state,用于表示同步器的状态。state的值可以被多个线程同时访问和修改,因此需要使用volatile关键字来保证其可见性和原子性。

3. 定义一个等待队列,用于存储等待线程的节点。等待队列是一个FIFO的队列,每个节点都包含一个前驱节点和一个后继节点,用于维护队列的顺序。

4. 定义一个acquire()方法,用于实现线程的获取同步器。acquire()方法首先会尝试获取同步器的状态,如果状态符合要求,则直接返回;否则,将当前线程封装成一个节点,并加入等待队列中。如果当前线程是等待队列中的第一个节点,则会尝试获取同步器的状态,如果获取成功,则将当前节点从等待队列中移除,并返回。

5. 定义一个release()方法,用于实现线程的释放同步器。release()方法首先会更新同步器的状态,然后尝试唤醒等待队列中的下一个节点。如果唤醒成功,则将该节点从等待队列中移除,并将其状态设置为可运行状态,从而使其可以继续执行。


http://www.ppmy.cn/news/76437.html

相关文章

PHP使用嵌入HTTP代理代码示例

以下是使用 PHP 嵌入 HTTP 代理的示例代码&#xff1a; php <?php // 设置代理服务器地址和端口 $proxy 127.0.0.1:8080; // 设置代理服务器用户名和密码&#xff08;如果需要验证&#xff09; $proxyAuth username:password; // 创建 cURL 句柄 $ch curl_init(); …

[CTF/网络安全] 攻防世界 baby_web 解题详析

[CTF/网络安全] 攻防世界 baby_web 解题详析 index.html & default.htmlindex.phpHTTP 302总结 题目描述&#xff1a;想想初始页面是哪个 index.html & default.html 初始页面的文件名一般为 index.html 或 default.html。这两个文件名都是 Web 服务器默认的首选文件…

Qt·事件处理机制

思维导读 一、事件简介 QT程序是事件驱动的, 程序的每个动作都是由内部某个事件所触发。QT事件的发生和处理成为程序运行的主线&#xff0c;存在于程序整个生命周期。 常见的QT事件类型如下: 键盘事件: 按键按下和松开 鼠标事件: 鼠标移动,鼠标按键的按下和松开 拖放事件: 用鼠…

STM32入门100步(第1步~第5步)

第一章 基础知识与平台建立 第1~2步 是时候学ARM了 1.1 为啥学? 什么是ARM? ARM处理器是英国Acorn有限公司设计的低功耗成本的第一款RISC(精简指令集)微处理器。全称为Advanced RISC Machine。ARM是一种性能出众的32位处理器的内核架构。1991年,一家叫ARM的公司在英国…

不需要策略模式也能避免满屏if/else

满屏if/else java 复制代码 public static void main(String[] args) { int a 1; if(a 1){ System.out.println("执行a1的逻辑"); }else if (a 2){ System.out.println("执行a2的逻辑"); }else if (a 3){ System.out.println("执行a3的逻辑&quo…

R语言实践——使用 rWCVP 生成自定义清单

使用 rWCVP 生成自定义清单 介绍1. 特有物种清单2. 近特有物种清单2.1 在塞拉利昂和另一地区出现的物种2.2 在塞拉利昂和相邻地区出现的物种 3. 生成自定义报告 介绍 除了允许用户从世界维管植物名录&#xff08;WCVP&#xff09;创建清单外&#xff0c;rWCVP还提供了修改清单…

python中的类型转换

文章目录 类型转换简介int()float()str()bool() 类型转换简介 所谓的类型转换&#xff0c;将一个类型的对象转换为其他对象。 类型转换不是改变对象本身的类型&#xff0c;而是将对象的值转换为新的对象。 类型转换四个函数 int() 、 float() 、 str() 、 bool() int() int()…

Autosar-以太网(UDP网络管理)

文章目录 前言一、网络协同机制二、运行模式1.状态转换流程Network Mode(正常工作模式)Repeat Message State(重复消息状态)Ready Sleep State(就绪睡眠状态)Normal Operation State(正常运行状态)Prepare Bus-Sleep Mode(准备睡眠模式)Bus-Sleep Mode(睡眠模式/低功…