JUC 包中的 Atomic 原子类总结

2024-07-21 1436阅读
JUC 包中的 Atomic 原子类总结 人不走空

                                                                      

      🌈个人主页:人不走空      

💖系列专栏:算法专题

⏰诗词歌赋:斯是陋室,惟吾德馨

JUC 包中的 Atomic 原子类总结

目录

      🌈个人主页:人不走空      

💖系列专栏:算法专题

⏰诗词歌赋:斯是陋室,惟吾德馨

Atomic 原子类介绍

基本类型原子类

数组类型原子类

引用类型原子类

对象的属性修改类型原子类

作者其他作品:


 

JUC 包中的 Atomic 原子类总结

JavaGuide官方网站:javaguide.cn

Atomic 原子类介绍

Atomic 翻译成中文是“原子”的意思。在化学上,原子是构成物质的最小单位,在化学反应中不可分割。在编程中,Atomic 指的是一个操作具有原子性,即该操作不可分割、不可中断。即使在多个线程同时执行时,该操作要么全部执行完成,要么不执行,不会被其他线程看到部分完成的状态。

原子类简单来说就是具有原子性操作特征的类。

java.util.concurrent.atomic 包中的 Atomic 原子类提供了一种线程安全的方式来操作单个变量。

Atomic 类依赖于 CAS(Compare-And-Swap,比较并交换)乐观锁来保证其方法的原子性,而不需要使用传统的锁机制(如 synchronized 块或 ReentrantLock)。

这篇文章我们只介绍 Atomic 原子类的概念,具体实现原理可以阅读笔者写的这篇文章:什么是乐观锁和悲观锁?Java 中 CAS 是如何实现的?。

JUC 包中的 Atomic 原子类总结

JUC原子类概览

根据操作的数据类型,可以将 JUC 包中的原子类分为 4 类:

1、基本类型

使用原子的方式更新基本类型

  • AtomicInteger:整型原子类

  • AtomicLong:长整型原子类

  • AtomicBoolean:布尔型原子类

    2、数组类型

    使用原子的方式更新数组里的某个元素

    • AtomicIntegerArray:整型数组原子类

    • AtomicLongArray:长整型数组原子类

    • AtomicReferenceArray:引用类型数组原子类

      3、引用类型

      • AtomicReference:引用类型原子类

      • AtomicMarkableReference:原子更新带有标记的引用类型。该类将 boolean 标记与引用关联起来,也可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。

      • AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于解决原子的更新数据和数据的版本号,可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。

        🐛 修正(参见:issue#626:https://github.com/Snailclimb/JavaGuide/issues/626) : AtomicMarkableReference 不能解决 ABA 问题。

        4、对象的属性修改类型

        • AtomicIntegerFieldUpdater:原子更新整型字段的更新器

        • AtomicLongFieldUpdater:原子更新长整型字段的更新器

        • AtomicReferenceFieldUpdater:原子更新引用类型里的字段

          基本类型原子类

          使用原子的方式更新基本类型

          • AtomicInteger:整型原子类

          • AtomicLong:长整型原子类

          • AtomicBoolean:布尔型原子类

            上面三个类提供的方法几乎相同,所以我们这里以 AtomicInteger 为例子来介绍。

            AtomicInteger 类常用方法 :

            public final int get() //获取当前的值
            public final int getAndSet(int newValue)//获取当前的值,并设置新的值
            public final int getAndIncrement()//获取当前的值,并自增
            public final int getAndDecrement() //获取当前的值,并自减
            public final int getAndAdd(int delta) //获取当前的值,并加上预期的值
            boolean compareAndSet(int expect, int update) //如果输入的数值等于预期值,则以原子方式将该值设置为输入值(update)
            public final void lazySet(int newValue)//最终设置为newValue, lazySet 提供了一种比 set 方法更弱的语义,可能导致其他线程在之后的一小段时间内还是可以读到旧的值,但可能更高效。
            

            AtomicInteger 类使用示例 :

            // 初始化 AtomicInteger 对象,初始值为 0
            AtomicInteger atomicInt = new AtomicInteger(0);
            // 使用 getAndSet 方法获取当前值,并设置新值为 3
            int tempValue = atomicInt.getAndSet(3);
            System.out.println("tempValue: " + tempValue + "; atomicInt: " + atomicInt);
            // 使用 getAndIncrement 方法获取当前值,并自增 1
            tempValue = atomicInt.getAndIncrement();
            System.out.println("tempValue: " + tempValue + "; atomicInt: " + atomicInt);
            // 使用 getAndAdd 方法获取当前值,并增加指定值 5
            tempValue = atomicInt.getAndAdd(5);
            System.out.println("tempValue: " + tempValue + "; atomicInt: " + atomicInt);
            // 使用 compareAndSet 方法进行原子性条件更新,期望值为 9,更新值为 10
            boolean updateSuccess = atomicInt.compareAndSet(9, 10);
            System.out.println("Update Success: " + updateSuccess + "; atomicInt: " + atomicInt);
            // 获取当前值
            int currentValue = atomicInt.get();
            System.out.println("Current value: " + currentValue);
            // 使用 lazySet 方法设置新值为 15
            atomicInt.lazySet(15);
            System.out.println("After lazySet, atomicInt: " + atomicInt);
            

            输出:

            tempValue: 0; atomicInt: 3
            tempValue: 3; atomicInt: 4
            tempValue: 4; atomicInt: 9
            Update Success: true; atomicInt: 10
            Current value: 10
            After lazySet, atomicInt: 15
            

            数组类型原子类

            使用原子的方式更新数组里的某个元素

            • AtomicIntegerArray:整形数组原子类

            • AtomicLongArray:长整形数组原子类

            • AtomicReferenceArray:引用类型数组原子类

              上面三个类提供的方法几乎相同,所以我们这里以 AtomicIntegerArray 为例子来介绍。

              AtomicIntegerArray 类常用方法:

              public final int get(int i) //获取 index=i 位置元素的值
              public final int getAndSet(int i, int newValue)//返回 index=i 位置的当前的值,并将其设置为新值:newValue
              public final int getAndIncrement(int i)//获取 index=i 位置元素的值,并让该位置的元素自增
              public final int getAndDecrement(int i) //获取 index=i 位置元素的值,并让该位置的元素自减
              public final int getAndAdd(int i, int delta) //获取 index=i 位置元素的值,并加上预期的值
              boolean compareAndSet(int i, int expect, int update) //如果输入的数值等于预期值,则以原子方式将 index=i 位置的元素值设置为输入值(update)
              public final void lazySet(int i, int newValue)//最终 将index=i 位置的元素设置为newValue,使用 lazySet 设置之后可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
              

              AtomicIntegerArray 类使用示例 :

              int[] nums = {1, 2, 3, 4, 5, 6};
              // 创建 AtomicIntegerArray
              AtomicIntegerArray atomicArray = new AtomicIntegerArray(nums);
              // 打印 AtomicIntegerArray 中的初始值
              System.out.println("Initial values in AtomicIntegerArray:");
              for (int j = 0; j 
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]