热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java并发编程札记-(三)JUC原子类-03原子方式更新数组

今天学习AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray,这几个类的共同特点是都提供数组的原子方式访问和更新功能。下面以AtomicL

今天学习AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray,这几个类的共同特点是都提供数组的原子方式访问和更新功能。下面以AtomicLongArray为代表,对这些类进行介绍。

AtomicLongArray可以用原子方式更新其元素的long数组,实例提供long类型数组的原子方式访问和更新功能。

API

//构造方法摘要
AtomicLongArray(int length)
//创建给定长度的新 AtomicLongArray。
AtomicLongArray(long[] array)
//创建与给定数组具有相同长度的新 AtomicLongArray,并从给定数组复制其所有元素。
//方法摘要
long addAndGet(int i, long delta)
//以原子方式将给定值添加到索引 i 的元素。
boolean compareAndSet(int i, long expect, long update)
//如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
long decrementAndGet(int i)
//以原子方式将索引 i 的元素减1。
long get(int i)
//获取位置 i 的当前值。
long getAndAdd(int i, long delta)
//以原子方式将给定值与索引 i 的元素相加。
long getAndDecrement(int i)
//以原子方式将索引 i 的元素减 1。
long getAndIncrement(int i)
//以原子方式将索引 i 的元素加 1。
long getAndSet(int i, long newValue)
//以原子方式将位置 i 的元素设置为给定值,并返回旧值。
long incrementAndGet(int i)
//以原子方式将索引 i 的元素加1。
void lazySet(int i, long newValue)
//最终将位置 i 的元素设置为给定值。
int length()
//返回该数组的长度。
void set(int i, long newValue)
//将位置 i 的元素设置为给定值。
String toString()
//返回数组当前值的字符串表示形式。
boolean weakCompareAndSet(int i, long expect, long update)
//如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
//以下是JDK1.8新增的部分
long getAndUpdate(int i, LongUnaryOperator updateFunction)
//将当前值以原子方式更新为updateFunction方法的结果,并返回更新前的值
long updateAndGet(int i, LongUnaryOperator updateFunction)
//将当前值以原子方式更新为updateFunction方法的结果,并返回更新后的值
long getAndAccumulate(int i, long x, LongBinaryOperator accumulatorFunction)
//将当前值以原子方式更新为updateFunction方法的结果(方法参数为x和当前值),并返回更新前的值
long accumulateAndGet(int i, long x, LongBinaryOperator accumulatorFunction)
//将当前值以原子方式更新为updateFunction方法的结果(方法参数为x和当前值),并返回更新后的值

例1:long型数组的原子访问和更新

import java.util.Arrays;

public class AtomicLongArrayDemo {

public static void main(String[] args) {
for (int i = 0; i <100; i++) {
Thread thread = new Thread() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(("[100, 100, 100, 100, 100]").equals(Arrays.toString(Counter.addOne())))
System.out.println("计数器值最终值为[100, 100, 100, 100, 100]");
}
};
thread.start();
}
}
}
class Counter {
private static long[] counter = new long[]{0, 0, 0, 0, 0};

public static long[] addOne() {
for(int i=0;i ++counter[i];
return counter;
}
}

测试程序在连续运行100次将数组所有元素加一的操作后,判断计数器值是否为100, 100, 100, 100, 100],如果为100, 100, 100, 100, 100]就打印计数器值最终值为100, 100, 100, 100, 100],否则就什么都不打印。
数次运行程序后,发现大多数结果是什么都没有打印,说明此计数器在多线程环境下不可用。

import java.util.concurrent.atomic.AtomicLongArray;

public class AtomicLongArrayDemo {

public static void main(String[] args) {
for (int i = 0; i <100; i++) {
Thread thread = new Thread() {
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (("[100, 100, 100, 100, 100]").equals(Counter.addOne().toString())) {
System.out.println("计数器值最终值为[100, 100, 100, 100, 100]");
}
}
};
thread.start();
}
}
}

class Counter {
private static AtomicLongArray counter = new AtomicLongArray(new long[] {0, 0, 0, 0, 0});

public static AtomicLongArray addOne() {
for(int i=0;i counter.incrementAndGet(i);
return counter;
}
}

数次运行程序后,发现结果全部为计数器值最终值为[100, 100, 100, 100, 100]

实现原理

与AtomicLong相同,AtomicLong也是基于CAS实现的。

AtomicIntegerArray、AtomicReferenceArray与AtomicLongArray很相似,就不多做介绍了。

本文就讲到这里,想了解Java并发编程更多内容请参考:

  • Java并发编程札记-目录

END.


推荐阅读
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 预备知识可参考我整理的博客Windows编程之线程:https:www.cnblogs.comZhuSenlinp16662075.htmlWindows编程之线程同步:https ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
author-avatar
他w与他说
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有