2019独角兽企业重金招聘Python工程师标准>>>

AtomicIntegerArray

对int数组中元素的操作不是原子性的,所以存在并发操作时,我们应该使用AtomicIntegerArray类来代替int数组。
下面是验证演示代码:

public class AtomicIntegerArrayDemo {static AtomicIntegerArray aiArr = new AtomicIntegerArray(5);static int[] intArr = new int[5];/*** 并发测试,对数组的每个元素进行递增操作*/public static void main(String[] args) throws InterruptedException {ExecutorService threadPool = Executors.newCachedThreadPool();for(int t = 0; t < 5; t++) {threadPool.execute(() -> {for (int i = 0; i < 1000000; i++) {aiArr.getAndIncrement(i % 5);}});threadPool.execute(() -> {for (int i = 0; i < 1000000; i++) {intArr[i % 5]++;}});}threadPool.shutdown();boolean b = threadPool.awaitTermination(5, TimeUnit.SECONDS);if(b) {System.out.println("aiArr:" + aiArr.toString());System.out.println("intArr:" + Arrays.toString(intArr));}else{System.out.println("time out.");}}
}

运行结果:

D:\Java\jdk1.8.0_171\bin\java.exe "-javaagent:D:\JetBrains\IntelliJ IDEA
aiArr:[1000000, 1000000, 1000000, 1000000, 1000000]
intArr:[892703, 891096, 892369, 892372, 893754]

AtomicIntegerArray的常用方法:

//获取数组长度
int length()//获取数组中下标为i的元素的值
int get(int i)//设置数组中下标为i的元素的值为newValue
void set(int i, int newValue)//设置数组中下标为i的元素的值为newValue,返回以前的值
int getAndSet(int i, int newValue)//如果数组中下标为i的元素的值等于入参expect,则把值修改为update,并返回ture,如果不等则不修改并返回false
boolean compareAndSet(int i, int expect, int update)// arr[i]++
int getAndIncrement(int i)// arr[i]--
int getAndDecrement(int i)// ++arr[i]
int incrementAndGet(int i)// --arr[i]int decrementAndGet(int i)//数组中下标为i的元素的值加上delta,返回以前的值
int getAndAdd(int i, int delta)//数组中下标为i的元素的值加上delta,返回新的值
int addAndGet(int i, int delta)//1.8新增方法,更新当前值,返回以前的值
int getAndUpdate(int i, IntUnaryOperator updateFunction)// 1.8新增方法,更新当前值,返回更新后的值
int updateAndGet(int i, IntUnaryOperator updateFunction)// 1.8新增方法,更新当前值,返回以前的值
int getAndAccumulate(int i, int x, IntBinaryOperator accumulatorFunction)// 1.8新增方法,更新当前值,返回更新后的值
int accumulateAndGet(int i, int x, IntBinaryOperator accumulatorFunction)
*** 1.8新增方法演示*/
@Test
public void atomicIntegerArrayMethodTest(){AtomicIntegerArray arr = new AtomicIntegerArray(2);arr.set(0, 10);//lambda表达式中参数operand表示数组下标为0的元素当前值int i1 = arr.getAndUpdate(0, operand -> operand / 2);System.out.println(i1); // result: 10System.out.println(arr.get(0)); // result: 5int i2 = arr.updateAndGet(0, operand -> operand * 3);System.out.println(i2); // result: 15System.out.println(arr.get(0)); // result: 15//lambda表达式中参数left表示数组下标为0的元素当前值,right表示第二个参数2int i3 = arr.getAndAccumulate(0, 2, (left, right) -> left * right);System.out.println(i3); // result: 15System.out.println(arr.get(0)); // result: 30int i4 = arr.accumulateAndGet(0, 2, (left, right) -> left * right);System.out.println(i4); // result: 60System.out.println(arr.get(0)); // result: 60
}

AtomicIntegerFieldUpdater

AtomicIntegerFieldUpdater是用来原子的操作对象中int类型字段的。 下面是验证演示代码:

public class AtomicIntegerFieldUpdaterDemo {/*** 并发测试,对Counter的index字段进行递增操作*/public static void main(String[] args) throws InterruptedException {Counter counter1 = new Counter();AtomicIntegerFieldUpdater<Counter> counterIndexFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(Counter.class, "index");Counter counter2 = new Counter();ExecutorService threadPool = Executors.newCachedThreadPool();for(int t = 0; t < 5; t++) {threadPool.execute(() -> {for (int i = 0; i < 1000000; i++) {counter1.index++;}});threadPool.execute(() -> {for (int i = 0; i < 1000000; i++) {counterIndexFieldUpdater.getAndIncrement(counter2);}});}threadPool.shutdown();boolean b = threadPool.awaitTermination(5, TimeUnit.SECONDS);if(b) {System.out.println("counter1.index:" + counter1.index);System.out.println("counter2.index:" + counterIndexFieldUpdater.getAndIncrement(counter2));}else{System.out.println("time out.");}}
}class Counter{/** 必须是volatile修饰的 */public volatile int index = 0;
}

运行结果:

D:\Java\jdk1.8.0_171\bin\java.exe "-javaagent:D:\JetBrains\IntelliJ IDEA
counter1.index:4192522
counter2.index:5000000

值得注意的是,使用的时候注意如下几点:

  1. 字段必须是volatile类型的,在线程之间共享变量时保证立即可见
  2. 字段的描述类型(修饰符public/protected/default/private)是与调用者与操作对象字段的关系一致。也就是说调用者能够直接操作对象字段,那么就可以反射进行原子操作。
  3. 对于父类的字段,子类是不能直接操作的,尽管子类可以访问父类的字段。
  4. 只能是实例变量,不能是类变量,也就是说不能加static关键字。
  5. 只能是可修改变量,不能使final变量,因为final的语义就是不可修改。
  6. 对于AtomicIntegerFieldUpdater和AtomicLongFieldUpdater只能修改int/long类型的字段,不能修改其包装类型(Integer/Long)。如果要修改包装类型就需要使用AtomicReferenceFieldUpdater。
    参考:Java并发学习(九)-AtomicIntegerFieldUpdater字段原子更新类

AtomicIntegerArray的常用方法:

//创建AtomicIntegerFieldUpdater对象,tclass为需要操作对象的类型,fieldName为需要操作字段名称
static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName)//如果obj中指定字段的值等于expect,则把该字段的值设为update
boolean compareAndSet(T obj, int expect, int update) //把obj中指定字段的值设置为newValue
void set(T obj, int newValue);//返回obj中指定字段的值
int get(T obj);//把obj中指定字段的值设置为newValue,返回以前的值
int getAndSet(T obj, int newValue)//i++
int getAndIncrement(T obj)//++i
int incrementAndGet(T obj)//i--
int getAndDecrement(T obj)
//--i
decrementAndGet(T obj)//把obj中指定字段的值加上delta,返回以前的值
int getAndAdd(T obj, int delta)//把obj中指定字段的值加上delta,返回更新后的值
int addAndGet(T obj, int delta)//1.8新增方法,更obj中指定字段的值,返回以前的值
int getAndUpdate(T obj, IntUnaryOperator updateFunction)//1.8新增方法,更obj中指定字段的值,返回更新后的值
int updateAndGet(T obj, IntUnaryOperator updateFunction)//1.8新增方法,更obj中指定字段的值,返回以前的值
int getAndAccumulate(T obj, int x, IntBinaryOperator accumulatorFunction)//1.8新增方法,更obj中指定字段的值,返回更新后的值
int accumulateAndGet(T obj, int x, IntBinaryOperator accumulatorFunction)

转载于:https://my.oschina.net/u/2424727/blog/1933993

AtomicIntegerArray和AtomicIntegerFieldUpdater相关推荐

  1. java list 取几个字段组装成map_java.util.concurrent 并发包诸类概览

    并发容器 这些容器的关键方法大部分都实现了线程安全的功能,却不使用同步关键字 (synchronized).值得注意的是 Queue 接口本身定义的几个常用方法的区别, add 方法和 offer 方 ...

  2. 精通安卓性能优化-第五章(三)

    Concurrency 在java.util.concurrent.atomic和java.util.concurrent.locks包中定义了更多的类.java.util.concurrent.at ...

  3. 2020java面试必问,找不到工作你找我(一)

    Java 面试宝典 第一章 内容介绍 20 第二章 JavaSE 基础 21 一. Java 面向对象 21 1.面向对象都有哪些特性以及你对这些特性的理解 21 2.访问权限修饰符 public.p ...

  4. concurrent

    一次聊天,谈到了死锁的解决.可重入锁等等,突然发现这些离自己很远,只有一些读书时的概念涌入脑海,但各自的应用场景怎么都无法想出.痛定思痛,决定看看concurrent包里涉及并发的类及各自的应用场景. ...

  5. 8w字 | Java并发编程 全套功法

    介绍:CSDN统计字数:77153字,Java多线程从入门到精通,由浅入深.[建议收藏!] ❤️❤️❤️❤️❤️❤️ 点击主页发现更多好文❤️❤️❤️❤️❤️❤️ 文章目录 引言 什么是进程,线程? ...

  6. AtomicIntegerFieldUpdater字段原子更新类

    前面讲的两个AtomicInteger和AtomicIntegerArray,这两个都是在最初设计编码时候就已经考虑到了需要保证原子性.但是往往有很多情况就是,由于需求的更改,原子性需要在后面加入,类 ...

  7. 并发之AtomicIntegerArray

    5 并发之AtomicIntegerArray     该类是Java对Integer数组支持的原子性操作:在认识这个类之前我们先来看一个方法,这个方法是Integer类中的:  public sta ...

  8. AtomicIntegerArray类详解

    介绍 java.util.concurrent.atomic.AtomicIntegerArray类提供了可以以原子方式读取和写入的底层int数组的操作,还包含高级原子操作. AtomicIntege ...

  9. 4.4.6 数组也能无锁:AtomicIntegerArray

    数组也可以实现cas操作,有以下几个类以及用法如下: public class AtomicTntegerArrayTest {public static void main(String[] arg ...

最新文章

  1. Ubuntu 14.04下java开发环境的搭建--2--Eclipse的安装
  2. 智能车竞赛技术报告 | 智能车视觉 - 中国矿业大学 - 会飞的车
  3. linux rpc语言,Linux下RPC的hello world
  4. [JAVA]引入目录下所有jar包等问题
  5. Jetty 类载入问题处理
  6. pandas学习笔记三之处理丢失数据
  7. jeecg 服务器 + linux + nginx 安装
  8. ubuntu 电源按钮操作_电源菜单和按笔记本电脑电源按钮时缺少休眠
  9. paypal 支付接口 php,PHP整合PayPal支付
  10. 房产中介管理系统软件的开发和使用(附源码)
  11. 使用java对pdf文档进行分解和合成
  12. 论频谱中负频率的物理意义
  13. 抖音,新的流量洼地?
  14. android拉起软键盘,移动端JavaScript拉起软键盘
  15. C++——次幂运算表示
  16. [计算机网络]十、TCP的拥塞控制和4个计时器、常用协议原理和命令
  17. WebMagic爬取码市、猪八戒、一品威客外包数据
  18. Go Web快速开发框架 Fiber
  19. 美眉都是可爱的…… (美图)
  20. 【转】售前的成长故事(19篇)

热门文章

  1. python中汉字与变量不可同时出现_Python语言应用培训课(选择练习)
  2. 四天人工智能 python入门体验课_百度深度学习7天打卡营,用Python+AI识别“青你2”小姐姐的高颜值...
  3. springboot几种注入_Spring Boot中使用JdbcTemplate访问数据库
  4. UnityShader RenderTypeQueue 渲染顺序
  5. C# Job System
  6. matlab内存溢出的解决方案
  7. ASP.NET Core Web 应用程序系列(一)- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)...
  8. Apress Pro Android 2
  9. volatile的原理和实现机制
  10. JavaWeb:脚本标识