Java原子类中的AtomicInteger类详解

 更新时间:2023年10月24日 09:34:08   作者:liyong0829  
这篇文章主要介绍了Java原子类中的AtomicInteger类详解,原子类可以保证对"变量"操作的,原子性、有序性、可见性,我们可以通过AtomicInteger类,来看看它们是怎样工作的,需要的朋友可以参考下

原子类

在java.util.concurrent.atomic包下定义了一些对“变量”操作的“原子类”:

  • java.util.concurrent.atomic.AtomicInteger:对int变量操作的“原子类”;
  • java.util.concurrent.atomic.AtomicLong:对long变量操作的“原子类”;
  • java.util.concurrent.atomic.AtomicBoolean:对boolean变量操作的“原子类”;

它们可以保证对“变量”操作的:原子性、有序性、可见性。

AtomicInteger类示例

我们可以通过AtomicInteger类,来看看它们是怎样工作的

//线程类:

public class MyThread extends Thread {
     //static int a = 0;
    static AtomicInteger a = new AtomicInteger();// 表示整数0

    @Override
    public void run() {
        for (int i = 0; i < 200000; i++) {
            // a++;
            a.getAndIncrement();
        }
        System.out.println("子线程执行完毕");
    }
}

//测试类:

public class Test {
    public static void main(String[] args) throws InterruptedException {

        // 案例:一条子线程和一条主线程都对共享变量a进行++操作,每条线程对a++操作400000次
        new MyThread().start();

        for (int i = 0; i < 200000; i++) {
            //MyThread.a++;
            MyThread.a.getAndIncrement();
        }

        // 为了保证子线程和主线程都执行完毕
        Thread.sleep(3000);

        // 打印最终共享变量a的值(子线程,主线程对a的操作都执行完毕了)
        System.out.println("最终:"+ MyThread.a.get());

  }
}

我们能看到,无论程序运行多少次,其结果总是正确的!

AtomicInteger类的工作原理-CAS机制

在这里插入图片描述

AtomicIntegerArray类示例

常用的数组操作的原子类:

1).java.util.concurrent.atomic.AtomicIntegerArray:对int数组操作的原子类。 int[]

2).java.util.concurrent.atomic.AtomicLongArray:对long数组操作的原子类。long[]

3).java.util.concurrent.atomic.AtomicReferenceArray:对引用类型数组操作的原子类。Object[]

数组的多线程并发访问的安全性问题:

//线程类:

public class MyThread extends Thread {
    public static int[] arr = new int[1000];

    @Override
    public void run() {
        for (int i = 0; i < arr.length(); i++) {
            arr[i]++;
        }
        System.out.println("结束");
    }
}

//测试类:

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 1000; i++) {
            new MyThread().start();//创建1000个线程,每个线程为数组的每个元素+1
        }

        Thread.sleep(1000 * 5);//让所有线程执行完毕

        System.out.println("主线程休息5秒醒来");
        for (int i = 0; i < MyThread.arr.length; i++) {
            System.out.println(MyThread.arr[i]);
        }
    }
}

//正常情况,数组的每个元素最终结果应为:1000,而实际打印:

1000
1000
1000
1000
999
999
999
999
999
999
999
999
1000
1000
1000
1000

可以发现,有些元素并不是1000.

//为保证数组的多线程安全,改用AtomicIntegerArray类,演示:

//线程类:

public class MyThread extends Thread {
 
    //改用原子类,使用数组构造
    public static AtomicIntegerArray arr = new AtomicIntegerArray(1000);
    @Override
    public void run() {
        for (int i = 0; i < arr.length(); i++) {
            arr.addAndGet(i, 1);//将i位置上的元素 + 1
        }
        System.out.println("结束");
    }
}

测试类 

  public class Demo {
      public static void main(String[] args) throws InterruptedException {
          for (int i = 0; i < 1000; i++) {
              new MyThread().start();
          }
          Thread.sleep(1000 * 5);//让所有线程执行完毕
  
          System.out.println("主线程休息5秒醒来");
          for (int i = 0; i < MyThread.arr.length(); i++) {
              System.out.println(MyThread.arr.get(i));
          }
      }
  }

先在能看到,每次运行的结果都是正确的。

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

相关文章

  • 解决Mybatis-Plus中分页插件Page中total=0的问题

    解决Mybatis-Plus中分页插件Page中total=0的问题

    在使用Mybatis-Plus进行分页查询时,如果遇到`total=0`的情况,即使查询到了数据,也无法正确分页,这通常是由于依赖版本问题导致的,对于低版本,需要手动配置分页拦截器;对于高版本,可能需要添加特定的依赖配置来解决这个问题
    2025-11-11
  • Spring6当中获取Bean的四种方式小结

    Spring6当中获取Bean的四种方式小结

    Spring 为Bean 的获取提供了多种方式,通常包括4种方式,(也就是说在Spring中为Bean对象的创建准备了多种方案,目的是:更加灵活),本文将通过代码示例详细的给大家介绍了一下这四种方式,需要的朋友可以参考下
    2024-04-04
  • Java中八大包装类举例详解(通俗易懂)

    Java中八大包装类举例详解(通俗易懂)

    这篇文章主要介绍了Java中的包装类,包括它们的作用、特点、用途以及如何进行装箱和拆箱,包装类还提供了许多实用方法,如转换、获取基本类型值、比较和类型检测,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-02-02
  • Springboot集成Spring Security实现JWT认证的步骤详解

    Springboot集成Spring Security实现JWT认证的步骤详解

    这篇文章主要介绍了Springboot集成Spring Security实现JWT认证的步骤详解,帮助大家更好的理解和使用springboot,感兴趣的朋友可以了解下
    2021-02-02
  • 在idea中git实现里查看历史代码方式

    在idea中git实现里查看历史代码方式

    这篇文章主要介绍了在idea中git里查看历史代码的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • SpringBoot使用Scheduling实现定时任务的示例代码

    SpringBoot使用Scheduling实现定时任务的示例代码

    Spring Boot提供了一种方便的方式来实现定时任务,即使用Spring的@Scheduled注解,通过在方法上添加@Scheduled注解,我们可以指定方法在何时执行,本文我们就给大家介绍一下SpringBoot如何使用Scheduling实现定时任务,需要的朋友可以参考下
    2023-08-08
  • Springboot日志开启SLF4J过程解析

    Springboot日志开启SLF4J过程解析

    这篇文章主要介绍了Springboot日志开启SLF4J过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • Java中list.contains()的用法及拓展

    Java中list.contains()的用法及拓展

    List集合相信大家在开发过程中几乎都会用到,有时候难免会遇到集合里的数据是重复的,需要进行去除,下面这篇文章主要给大家介绍了关于Java中list.contains()的用法及拓展的相关资料,需要的朋友可以参考下
    2023-03-03
  • Springboot项目快速实现过滤器功能

    Springboot项目快速实现过滤器功能

    上篇文章已经给大家介绍了Springboot项目如何快速实现Aop功能,这篇文章给大家介绍Springboot项目如何快速实现过滤器功能,感兴趣的小伙伴可以参考阅读
    2023-03-03
  • macOS完全卸载Java开发环境详细教程

    macOS完全卸载Java开发环境详细教程

    Java开发环境的搭建是每一位Java程序员职业生涯的起点,其核心在于JDK(Java Development Kit)的正确安装与系统级环境变量的精准配置,这篇文章主要介绍了macOS完全卸载Java开发环境的相关资料,需要的朋友可以参考下
    2026-01-01

最新评论