关于Java中的CAS如何使用

 更新时间:2023年09月01日 10:27:03   作者:程序员徐师兄  
这篇文章主要介绍了关于Java中的CAS如何使用,CAS是Compare And Swap(比较并交换)的缩写,是一种非阻塞式并发控制技术,用于保证多个线程在修改同一个共享资源时不会出现竞争条件,从而避免了传统锁机制的各种问题,需要的朋友可以参考下

什么是CAS?

在Java中,CAS主要是通过java.util.concurrent.atomic包下的一些类和方法来实现的,下面我们就来详细了解一下CAS及其在Java中的使用。

CAS是一种非阻塞式并发控制技术,它主要用于解决多个线程同时访问同一个共享资源时可能出现的竞争条件问题。

为了保证数据的一致性和正确性,我们通常需要采取同步机制来对共享资源进行加锁。

但是,传统的锁机制在高并发场景下会带来严重的性能问题,因为所有线程都需要等待锁的释放才能进行操作,这就会导致大量线程的阻塞和唤醒,进而降低了系统的并发性能。

为了解决这个问题,CAS应运而生。

它是一种无锁的同步机制,可以在不使用锁的情况下实现数据的同步和并发控制。

CAS的核心思想是:在执行操作之前,先比较当前内存中的值是否等于期望值,如果相等,则执行修改操作;

如果不相等,则不执行修改操作,继续进行比较,直到内存中的值与期望值相等为止。

这个过程中不会出现线程的阻塞和唤醒,因此可以提高系统的并发性能。

Java中的CAS

在Java中,CAS主要是通过java.util.concurrent.atomic包下的一些类和方法来实现的。这些类和方法提供了一种原子操作的方式,可以保证多个线程同时访问同一个共享资源时不会出现竞争条件。

AtomicBoolean

AtomicBoolean类表示一个布尔类型的原子变量,它提供了一些原子操作方法

例如compareAndSet、getAndSet、weakCompareAndSet等,可以保证对该变量的操作是原子的。

下面是一个示例代码:

import java.util.concurrent.atomic.AtomicBoolean;
public class AtomicBooleanTest {
    private static AtomicBoolean flag = new AtomicBoolean(false);
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while (!flag.compareAndSet(false, true)) {
                System.out.println(Thread.currentThread().getName() + ": try again");
            }
            System.out.println(Thread.currentThread().getName() + ": success");
        },"Thread-1");
        Thread t2 = new Thread(() -> {
            while (!flag.compareAndSet(false, true)) {
                System.out.println(Thread.currentThread().getName() + ": try again");
            }
            System.out.println(Thread.currentThread().getName() + ": success");
        },"Thread-2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}

在这个例子中,我们创建了一个AtomicBoolean类型的变量flag,并定义了两个线程t1和t2,它们都会不断地尝试将flag的值由false变为true,直到成功为止。如果两个线程同时尝试修改flag的值,只有一个线程能够获得成功,另一个线程会继续尝试,直到成功为止。

AtomicInteger

AtomicInteger类表示一个整型的原子变量,它提供了一些原子操作方法,例如compareAndSet、getAndSet、incrementAndGet等,可以保证对该变量的操作是原子的。

下面是一个示例代码:

import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerTest {
    private static AtomicInteger count = new AtomicInteger(0);
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (int i = 0;i < 10000; i++) {
                count.incrementAndGet();
            }
        },"Thread-1");
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) {
                count.incrementAndGet();
            }
        },"Thread-2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("count = " + count.get());
    }
}

在这个例子中,我们创建了一个AtomicInteger类型的变量count,并定义了两个线程t1和t2,它们都会对count进行一万次的自增操作。由于AtomicInteger提供的incrementAndGet方法是原子的,因此多个线程同时对count进行自增操作不会出现竞争条件,最终count的值会是正确的。

AtomicReference

AtomicReference类表示一个引用类型的原子变量,它提供了一些原子操作方法,例如compareAndSet、getAndSet、weakCompareAndSet等,可以保证对该变量的操作是原子的。

下面是一个示例代码:

import java.util.concurrent.atomic.AtomicReference;
public class AtomicReferenceTest {
    private static class Student{
        private String name;
        private int age;
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
        public void setName(String name) {
            this.name = name;
        }
        public void setAge(int age) {
            this.age = age;
        }
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    private static AtomicReference<Student> student = new AtomicReference<>(new Student("张三", 18));
    public static void main(String[] args) {
        Student newStudent = new Student("李四", 20);
        student.compareAndSet(student.get(), newStudent);
        System.out.println(student.get());
    }
}

在这个例子中,我们创建了一个AtomicReference类型的变量student,并定义了一个Student类型的对象newStudent。

我们通过compareAndSet方法将原子变量student的值从原来的Student对象修改为newStudent对象,由于AtomicReference提供的compareAndSet方法是原子的,因此多个线程同时对student进行修改操作不会出现竞争条件。

总结

CAS是一种非阻塞式的并发控制技术,它可以在不使用锁的情况下实现数据的同步和并发控制,从而提高系统的并发性能。

在Java中,CAS主要是通过java.util.concurrent.atomic包下的一些类和方法来实现的,它们提供了一种原子操作的方式,可以保证多个线程同时访问同一个共享资源时不会出现竞争条件。

实际开发中,如果需要对共享资源进行并发控制,建议优先考虑使用CAS技术。

到此这篇关于关于Java中的CAS如何使用的文章就介绍到这了,更多相关Java中的CAS内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • packages思维及使用Java添加Android平台特定实现

    packages思维及使用Java添加Android平台特定实现

    这篇文章主要为大家介绍了packages思维及使用Java添加Android平台特定实现在Flutter框架里的体现和运用详解,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • springCloud Gateway StripPrefix和PrefixPath过滤器的区别及说明

    springCloud Gateway StripPrefix和PrefixPath过滤器的区别及说

    这篇文章主要介绍了springCloud Gateway StripPrefix和PrefixPath过滤器的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • spring中@ControllerAdvice 注解的使用

    spring中@ControllerAdvice 注解的使用

    @ControllerAdvice注解是Spring3.2中新增的注解,主要用于Controller的全局配置,本文就来介绍一下spring中@ControllerAdvice 注解的使用,感兴趣的可以了解一下
    2024-09-09
  • Java后端接入微信小程序登录功能(登录流程)

    Java后端接入微信小程序登录功能(登录流程)

    这篇文章主要介绍了Java后端接入微信小程序登录功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • Springmvc发送json数据转Java对象接收

    Springmvc发送json数据转Java对象接收

    这篇文章主要介绍了Springmvc发送json数据转Java对象接收,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • 关于弗洛伊德算法求最短路径详解

    关于弗洛伊德算法求最短路径详解

    这篇文章主要介绍了关于弗洛伊德算法求最短路径详解,弗洛伊德算法VS迪杰斯特拉算法:迪杰斯特拉算法通过选定的被访问顶点,求出从出发访问顶点到其他项点的最短路径:弗洛伊德算法中每-个顶点都是出发访问点,需要的朋友可以参考下
    2023-07-07
  • Java JMH测试与JMeter测试的区别及说明

    Java JMH测试与JMeter测试的区别及说明

    JMH专注微观基准测试,测量Java代码性能;JMeter用于宏观性能测试,评估系统负载与压力,两者互补,JMH优化关键代码,JMeter验证整体性能
    2025-08-08
  • SpringBoot 动态配置邮箱发件人过程解析

    SpringBoot 动态配置邮箱发件人过程解析

    这篇文章主要介绍了SpringBoot 动态配置邮箱发件人过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • Java中for循环的执行过程分析

    Java中for循环的执行过程分析

    这篇文章主要介绍了Java中for循环的执行过程,实例分析了for循环的执行原理与顺序,对于深入理解Java具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Spring中@Autowired注解在不同方法的写法示例

    Spring中@Autowired注解在不同方法的写法示例

    这篇文章主要为大家介绍了Spring中@Autowired注解在不同方法的写法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01

最新评论