突击并发编程JUC系列-数组类型AtomicLongArray
突击并发编程JUC系列演示代码地址: https://github.com/mtcarpenter/JavaTutorial
上一个章节我们学习原子更新基本类型类,如果没有印象的小伙伴可以通过底部的链接回头看下,本章节主要介绍原子更新数组类型。
数组类型
数组类型就是通过原子的方式更新数组里的某个元素,Atomic包提供了以下4个类。
AtomicLongArray 常用方法如下
方法名 |
说明 |
---|---|
|
以原子方式将位置 |
|
以原子方式将索引 |
|
以原子方式将索引 |
|
以原子方式将索引 |
|
以原子方式将输入值与数组中索引i的元素相加。 |
|
将位置 |
|
原子地将给定的值添加到索引 |
|
获取位置 |
|
最终将位置 |
|
返回数组的长度。 |
|
将位置 |
boolean compareAndSet(int i,int expect,int update) |
如果当前值 |
|
如果当前值 |
........ |
........ |
|
|
|
使用将给定函数应用给当前值和给定值的结果原子更新当前值,返回旧值 |
|
使用将给定函数应用给当前值和给定值的结果原子更新当前值,返回新值 |
........ |
小试牛刀
指定大小
public class AtomicExample4 {
/**
* 初始化 数组长度为 10
*/
private static AtomicLongArray arr = new AtomicLongArray(5);
private static LongUnaryOperator longUnaryOperator = new LongUnaryOperator() {
@Override
public long applyAsLong(long operand) {
// 当前索引 + 10
return operand + 10;
}
};
private static LongBinaryOperator accumulatorFunction = new LongBinaryOperator() {
@Override
public long applyAsLong(long left, long right) {
return left + right;
}
};
public static void main(String[] args) {
for (int i = 0; i < arr.length(); i++) {
System.out.println("i-" + i + "=" + arr.get(i));
}
// 以原子方式给当前索引下标为(0)值加1,返回新值 (i++): 0
System.out.println("索引 0 incrementAndGet=" + arr.getAndIncrement(0));
// 以原子方式给当前索引下标为(0)值加1,,返回新值(++i) 两次增加 : 2
System.out.println("索引 0 incrementAndGet=" + arr.incrementAndGet(0));
//以原子方式给当前索引下标为(0)值减少 1,返回旧值 (i--):2
System.out.println("索引 0 incrementAndGet=" + arr.getAndDecrement(0));
//以原子方式给当前索引下标为(0)值减少 1,返回旧值 (--i):0
System.out.println("索引 0 incrementAndGet=" + arr.decrementAndGet(0));
// 以原子方式将输入的数值与实例中的值(AtomicLongArray(0)里的value)相加,并返回结果 : 100
System.out.println("索引 0 addAndGet=" + arr.addAndGet(0, 100));
// 获取 AtomicLongArray 的 value 100
System.out.println("索引 0 get=" + arr.get(0));
System.out.println("*********** JDK 1.8 ***********");
//使用将给定函数应用给当前值和给定值的结果原子更新当前值,返回上一个值
// 索引下标为 0 执行指定函数 结果为 100 + 10
System.out.println("索引 0 getAndUpdate=" + arr.updateAndGet(0, longUnaryOperator));
// 索引下标为 1 执行指定函数 结果为 0 + 10
System.out.println("索引 1 getAndUpdate=" + arr.updateAndGet(1, longUnaryOperator));
// 使用给定函数应用给指定下标和给定值的结果原子更新当前值,并返回结果 20
System.out.println("索引 1 accumulateAndGet=" + arr.accumulateAndGet(1, 10, accumulatorFunction));
}
}
运行结果如下:
i-0=0
i-1=0
i-2=0
i-3=0
i-4=0
索引 0 incrementAndGet=0
索引 0 incrementAndGet=2
索引 0 incrementAndGet=2
索引 0 incrementAndGet=0
索引 0 addAndGet=100
索引 0 get=100
*********** JDK 1.8 ***********
索引 0 getAndUpdate=110
索引 1 getAndUpdate=10
索引 1 accumulateAndGet=20
通过数组
public class AtomicExample5 {
public static void main(String[] args) {
/**
* 初始化 数组
*/
long arrs[] = {5, 20, 30, 40, 50};
/**
* 将初始化数组的值 赋值给 AtomicLongArray
*/
AtomicLongArray arr = new AtomicLongArray(arrs);
System.out.println("arr length=" + arr.length());
for (int i = 0; i < arr.length(); i++) {
System.out.println("i-" + i + "=" + arr.get(i));
}
// 通过set 给指定元素赋值
arr.set(0, 10);
// 通过 get 获取下标为 0 的值
System.out.println("索引 0 get = " + arr.get(0));
//如果"指定索引的值" = "预期值" 就将指定的值更新为需要"更新的值"
// 索引为 2 如果是 20 则相等,将值更新为 30
arr.compareAndSet(2, 30, 300);
System.out.println("compareAndSet 更新索引 2 的值= " + arr.get(2));
// 与 compareAndSet 不管初始值是否为预期值都可能会无法更新该值。
arr.weakCompareAndSet(2, 300, 3000);
System.out.println("weakCompareAndSet 更新索引 2 的值= " + arr.get(2));
}
}
- 注意知识
-
compareAndSet
: 指定索引值
和给定预期值
如果相等,则修改值为更新值
. -
weakCompareAndSet
: 此方法跟compareAndSet
类似,但是不管初始值是否为预期值都可能会无法更新该值。
-
运行结果如下:
arr length=5
i-0=5
i-1=20
i-2=30
i-3=40
i-4=50
索引 0 get = 10
compareAndSet 更新索引 2 的值= 300
weakCompareAndSet 更新索引 2 的值= 3000
总结
通过原子的方式更新数组里的某个元素,Atomic包提供了4个类, AtomicIntegerArray
、 AtomicLongArray
、 AtomicReferenceArray
、 AtomicIntegerArray
,基本实现类似,在生活中使用频率比较少,如果看过上一个章节的小伙伴应该对此章节的案例相对就是轻车熟路,还不是很熟悉的小伙伴,建议尝试在电脑中运行案例,或者自己编码实现。
欢迎关注公众号 山间木匠 , 我是小春哥,从事 Java 后端开发,会一点前端、通过持续输出系列技术文章与文会友,如果本文能为您提供帮助,欢迎大家关注、在看、 点赞、分享支持,我们下期再见!
- BizTalk Orchestration execute Flat file disassembler ReceivePipeline
- MySQL基础入门系列之——字符与日期数据处理
- P2038 无线网络发射器选址
- ggplot2双坐标轴的解决方案
- Modifying namespace in XML document programmatically
- ggplot2学习笔记——图例系统及其调整函数
- 一款脑洞大开的表格可视化神器
- P3908 异或之和
- P1939 【模板】矩阵加速(数列)
- R语言学习笔记之——数据处理神器data.table
- P3389 【模板】高斯消元法
- hihoCoder #1195 : 高斯消元·一
- Python黑帽编程1.3 Python运行时与包管理工具
- P2421 A-B数对(增强版)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 微信支付之JSAPI公众号支付详解
- 浅谈keras中的batch_dot,dot方法和TensorFlow的matmul
- Python代码执行时间测量模块timeit用法解析
- Laravel框架实现简单的学生信息管理平台案例【附源码下载】
- numpy 矩阵形状调整:拉伸、变成一位数组的实例
- 使用Nibabel库对nii格式图像的读写操作
- ThinkPHP like模糊查询,like多匹配查询,between查询,in查询,一般查询书写方法
- 使用SimpleITK读取和保存NIfTI/DICOM文件实例
- php中上传文件的的解决方案
- python 实现两个npy档案合并
- PHP使用函数用法详解
- 读取nii或nii.gz文件中的信息即输出图像操作
- PHP实现SMTP邮件的发送实例
- 多个Laravel项目如何共用migrations详解
- PHP实现文字写入图片功能