介绍

java.util.concurrent.atomic.AtomicIntegerArray类提供了可以以原子方式读取和写入的底层int数组的操作,还包含高级原子操作。 AtomicIntegerArray支持对底层int数组变量的原子操作。 它具有获取和设置方法,如在变量上的读取和写入。 也就是说,一个集合与同一变量上的任何后续get相关联。 原子compareAndSet方法也具有这些内存一致性功能。

序号 方法 描述
1 public int addAndGet(int i, int delta) 原子地将给定的值添加到索引i的元素。
2 public boolean compareAndSet(int i, int expect, int update) 如果当前值==期望值,则将位置i处的元素原子设置为给定的更新值。
3 public int decrementAndGet(int i) 索引i处的元素原子并自减1
4 public int get(int i) 获取位置i的当前值。
5 public int getAndAdd(int i, int delta) 原子地将给定的值添加到索引i的元素。
6 public int getAndDecrement(int i) 索引i处的元素原子并自减1,并返回旧值。
7 public int getAndIncrement(int i) 将位置i处的元素原子设置为给定值,并返回旧值。
8 public int getAndSet(int i, int newValue) 将位置i处的元素原子设置为给定值,并返回旧值。
9 public int incrementAndGet(int i) 在索引i处以原子方式自增元素。
10 public void lazySet(int i, int newValue) 最终将位置i处的元素设置为给定值。
11 public int length() 返回数组的长度。
12 public void set(int i, int newValue) 将位置i处的元素设置为给定值。
13 public String toString() 返回数组的当前值的String表示形式。
14 public boolean weakCompareAndSet(int i, int expect, int update) 如果当前值==期望值,则将位置i处的元素原子设置为给定的更新值。

实例

package main.java.study;

import java.util.concurrent.atomic.AtomicIntegerArray;

public class AtomicIntegerArrayTest {

static class Increment implements Runnable {

public void run() {
            for (int i = 0; i < atomicIntegerArray.length(); i++) {
                int add = atomicIntegerArray.incrementAndGet(i);
                System.out.println("Thread " + Thread.currentThread().getId() + ", index " + i + ", value: " + add);
            }
        }
    }

static class Compare implements Runnable {

public void run() {
            for (int i = 0; i < atomicIntegerArray.length(); i++) {
                boolean swapped = atomicIntegerArray.compareAndSet(i, 2, 3);
                if (swapped) {
                    System.out.println("Thread " + Thread.currentThread().getId() + ", index " + i + ", value: 3");
                }
            }
        }
    }

private static AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(10);

public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < atomicIntegerArray.length(); i++) {
            atomicIntegerArray.set(i, 1);
        }

Thread t1 = new Thread(new Increment());
        Thread t2 = new Thread(new Compare());
        t1.start();
        t2.start();

t1.join();
        t2.join();

System.out.println("Values: ");
        for (int i = 0; i < atomicIntegerArray.length(); i++) {
            System.out.print(atomicIntegerArray.get(i) + " ");
        }

}

}

结果

Thread 11, index 0, value: 3
Thread 10, index 0, value: 2
Thread 10, index 1, value: 2
Thread 10, index 2, value: 2
Thread 10, index 3, value: 2
Thread 10, index 4, value: 2
Thread 10, index 5, value: 2
Thread 10, index 6, value: 2
Thread 10, index 7, value: 2
Thread 10, index 8, value: 2
Thread 10, index 9, value: 2
Values:
3 2 2 2 2 2 2 2 2 2

源码

AtomicIntegerArray 的public方法主要是call以下方法

public class AtomicIntegerArray implements java.io.Serializable {
    private static final long serialVersionUID = 2862133569453604235L;

private static final Unsafe unsafe = Unsafe.getUnsafe();

//获取数组起始位置的偏移量
    private static final int base = unsafe.arrayBaseOffset(int[].class);
    private static final int shift;
    private final int[] array;

static {

//获取数据元素的大小(size),int类型的是 4
        int scale = unsafe.arrayIndexScale(int[].class);
        if ((scale & (scale - 1)) != 0)
            throw new Error("data type scale not a power of two");

//numberOfLeadingZeros:返回无符号整型i的最高非零位前面的0的个数,int类型(4)的前置0个数为29

//下面表达式返回位移量,用于计算下标。用于<<操作符,表示乘以2^shift      2^2=4
        shift = 31 - Integer.numberOfLeadingZeros(scale);
    }

private long checkedByteOffset(int i) {
        if (i < 0 || i >= array.length)
            throw new IndexOutOfBoundsException("index " + i);

return byteOffset(i);
    }

//计算第i个元素的偏移量.

private static long byteOffset(int i) {
        return ((long) i << shift) + base;
    }

public AtomicIntegerArray(int length) {
        array = new int[length];
    }

public AtomicIntegerArray(int[] array) {
        // Visibility guaranteed by final field guarantees
        this.array = array.clone();
    }

public final int get(int i) {
        return getRaw(checkedByteOffset(i));
    }

private int getRaw(long offset) {
        return unsafe.getIntVolatile(array, offset);
    }

public final void set(int i, int newValue) {
        unsafe.putIntVolatile(array, checkedByteOffset(i), newValue);
    }

public final void lazySet(int i, int newValue) {
        unsafe.putOrderedInt(array, checkedByteOffset(i), newValue);
    }

}

数组在内存中是连续内存,如下图:

0 1 2 …… …… n-1

Java规定数组中的元素都是相同类型,因此数组中的每个元素的内存大小是相同的,也就是说,只要知道数组的起始位置,我们就可以算出指定下标的数组元素的内存位置

pos = base(起始位置) + i(下标) * size(类型大小)

AtomicIntegerArray类详解相关推荐

  1. OpenCV Mat类详解和用法(官网原文)

    参考文章:OpenCV Mat类详解和用法 我马克一下,日后更 官网原文链接:https://docs.opencv.org/3.2.0/d6/d6d/tutorial_mat_the_basic_i ...

  2. 转载:c+string类详解

    C++ string 类详解 </h1><div class="clear"></div><div class="postBod ...

  3. JDBC学习笔记02【ResultSet类详解、JDBC登录案例练习、PreparedStatement类详解】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

  4. JDBC学习笔记01【JDBC快速入门、JDBC各个类详解、JDBC之CRUD练习】

    黑马程序员-JDBC文档(腾讯微云)JDBC笔记.pdf:https://share.weiyun.com/Kxy7LmRm JDBC学习笔记01[JDBC快速入门.JDBC各个类详解.JDBC之CR ...

  5. Android复习14【高级编程:推荐网址、抠图片上的某一角下来、Bitmap引起的OOM问题、三个绘图工具类详解、画线条、Canvas API详解(平移、旋转、缩放、倾斜)、矩阵详解】

    目   录 推荐网址 抠图片上的某一角下来 8.2.2 Bitmap引起的OOM问题 8.3.1 三个绘图工具类详解 画线条 8.3.16 Canvas API详解(Part 1) 1.transla ...

  6. Java中的Runtime类详解

    Java中的Runtime类详解 1.类注释 /**Every Java application has a single instance of class Runtime that allows ...

  7. [NewLife.XCode]实体类详解

    NewLife.XCode是一个有10多年历史的开源数据中间件,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含 ...

  8. basicdatasourcefactory mysql_Java基础-DBCP连接池(BasicDataSource类)详解

    Java基础-DBCP连接池(BasicDataSource类)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 实际开发中"获得连接"或"释放资源 ...

  9. JAVA的StringBuffer类详解

    JAVA的StringBuffer类详解 StringBuffer类和String一样,也用来代表字符串,只是由于StringBuffer的内部实现方式和String不同,所以StringBuffer ...

最新文章

  1. Redis 官方可视化工具,功能真心强大!
  2. CashTippr:比特币现金MoneyButton打赏插件
  3. 红帽linux lnmp搭建,Linux(redhat5.4)下lnmp环境的搭建
  4. ActionScript 3 作用域内部细节介绍
  5. 将森林转换为对应的二叉树,若在二叉树中,结点u时结点v的父结点的父结点,则在原来的森林中,u和v可能具有的关系是( )
  6. Python闭包与装饰器
  7. pandas如何统计所有列的空值,并转化为list?
  8. 基于JAVA+SpringBoot+Mybatis+MYSQL的停车场管理系统
  9. HttpHandler和ashx要实现IRequiresSessionState接口才能访问Session信息(转载)
  10. android音频杂音问题_如何消除音频中的噪声?用这个简单好用的音频剪辑软件就够了...
  11. java 解析 xml中的冒号_Java jdom解析xml文件带冒号的属性
  12. How to enable/disable EWF
  13. 认知神经科学技术革命
  14. Bolt: Anonymous Payment Channels for Decentralized Currencies 学习笔记
  15. VC实现EXCEL转换为CSV格式
  16. 波浪下划线怎么设置_如何在word中的文字下面加波浪线
  17. 【笔记】【JavaScript】JSchallenger-Arrays对象-练习笔记
  18. 如何快速制作微信旅游相册?简单操作,效果精美!
  19. bte上了b网_酷站推荐 - tukkk.com - 小语种口语网
  20. arduino旋转编码器控制步进电机

热门文章

  1. Missing the OpenSSL lib
  2. 性能测试, 压力测试 , 负载测试和 容量测试 的区别与联系
  3. .Net 4.0并行库实用性演练
  4. Ibatis 升级 Mybatis
  5. LDAP之一:OpenLDAP管理员指南资料
  6. 如何自己动手写一个搜索引擎?我是一份害羞的教程
  7. php集合与数组的区别,java集合与数组的区别
  8. java处理json回车_json中换行符的处理方法示例介绍
  9. Jasypt 加密-整合SpringBoot
  10. SpringSecurity权限管理介绍