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类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java一个接口多个实现类的调用方式

    java一个接口多个实现类的调用方式

    这篇文章主要给大家介绍了关于java一个接口多个实现类的调用方式的相关资料,经测试确认,当一个接口有多个实现时,调用时只会执行一个,有时候需要多个实现调用,需要的朋友可以参考下
    2023-09-09
  • 数据结构与算法之手撕排序算法

    数据结构与算法之手撕排序算法

    排序算法看似简单,其实不同的算法中蕴涵着经典的算法策略。通过熟练掌握排序算法,就可以掌握基本的算法设计思想,本文主要介绍了Java中的排序算法,需要的朋友欢迎阅读
    2023-04-04
  • java教程散列表和树所对应容器类及HashMap解决冲突学习

    java教程散列表和树所对应容器类及HashMap解决冲突学习

    本篇篇文章是java教程,主要介绍了java教程散列表,树所对应容器类及HashMap解决冲突的学习,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2021-10-10
  • Java8 实现stream将对象集合list中抽取属性集合转化为map或list

    Java8 实现stream将对象集合list中抽取属性集合转化为map或list

    这篇文章主要介绍了Java8 实现stream将对象集合list中抽取属性集合转化为map或list的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • Spring Boot中优雅地处理参数传递的技巧分享

    Spring Boot中优雅地处理参数传递的技巧分享

    最近一直在学习Spring Boot,今天将其中的从前台过来的参数传递总结一下,下面这篇文章主要给大家介绍了关于Spring Boot中优雅地处理参数传递的技巧,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • springboot3.2整合mybatis-plus详细代码示例

    springboot3.2整合mybatis-plus详细代码示例

    这篇文章主要给大家介绍了关于springboot3.2整合mybatis-plus的相关资料,Spring Boot是一个非常流行的Java Web框架,可以快速地搭建Web应用程序,需要的朋友可以参考下
    2023-12-12
  • Java结构型设计模式之桥接模式详细讲解

    Java结构型设计模式之桥接模式详细讲解

    桥接,顾名思义,就是用来连接两个部分,使得两个部分可以互相通讯。桥接模式将系统的抽象部分与实现部分分离解耦,使他们可以独立的变化。本文通过示例详细介绍了桥接模式的原理与使用,需要的可以参考一下
    2022-09-09
  • SpringBoot项目嵌入RocketMQ的实现示例

    SpringBoot项目嵌入RocketMQ的实现示例

    本文主要介绍了SpringBoot项目嵌入RocketMQ的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-05-05
  • Java中HashSet和HashMap的区别_动力节点Java学院整理

    Java中HashSet和HashMap的区别_动力节点Java学院整理

    这篇文章主要介绍了Java中HashSet和HashMap的区别_动力节点Java学院整理,需要的朋友可以参考下
    2017-04-04
  • Spring Boot中优雅的获取yml文件工具类

    Spring Boot中优雅的获取yml文件工具类

    今天小编就为大家分享一篇关于Spring Boot中优雅的获取yml文件工具类,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12

最新评论