java并发AtomicIntegerArray

AtomicIntegerArray的原子性

AtomicIntegerArray的原子性是对数组的元素的,不是数组。

源码基于openjdk 1.8

/** ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************//******* Written by Doug Lea with assistance from members of JCP JSR-166* Expert Group and released to the public domain, as explained at* http://creativecommons.org/publicdomain/zero/1.0/*/package java.util.concurrent.atomic;
import java.util.function.IntUnaryOperator;
import java.util.function.IntBinaryOperator;
import sun.misc.Unsafe;/*** An {@code int} array in which elements may be updated atomically.* See the {@link java.util.concurrent.atomic} package* specification for description of the properties of atomic* variables.* @since 1.5* @author Doug Lea*/
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 {int scale = unsafe.arrayIndexScale(int[].class);if ((scale & (scale - 1)) != 0)throw new Error("data type scale not a power of two");shift = 31 - Integer.numberOfLeadingZeros(scale);}private long checkedByteOffset(int i) {if (i < 0 || i >= array.length)throw new IndexOutOfBoundsException("index " + i);return byteOffset(i);}private static long byteOffset(int i) {return ((long) i << shift) + base;}/*** Creates a new AtomicIntegerArray of the given length, with all* elements initially zero.** @param length the length of the array*/public AtomicIntegerArray(int length) {array = new int[length];}/*** Creates a new AtomicIntegerArray with the same length as, and* all elements copied from, the given array.** @param array the array to copy elements from* @throws NullPointerException if array is null*/public AtomicIntegerArray(int[] array) {// Visibility guaranteed by final field guaranteesthis.array = array.clone();}/*** Returns the length of the array.** @return the length of the array*/public final int length() {return array.length;}/*** Gets the current value at position {@code i}.** @param i the index* @return the current value*/public final int get(int i) {return getRaw(checkedByteOffset(i));}private int getRaw(long offset) {return unsafe.getIntVolatile(array, offset);}/*** Sets the element at position {@code i} to the given value.** @param i the index* @param newValue the new value*/public final void set(int i, int newValue) {unsafe.putIntVolatile(array, checkedByteOffset(i), newValue);}/*** Eventually sets the element at position {@code i} to the given value.** @param i the index* @param newValue the new value* @since 1.6*/public final void lazySet(int i, int newValue) {unsafe.putOrderedInt(array, checkedByteOffset(i), newValue);}/*** Atomically sets the element at position {@code i} to the given* value and returns the old value.** @param i the index* @param newValue the new value* @return the previous value*/public final int getAndSet(int i, int newValue) {return unsafe.getAndSetInt(array, checkedByteOffset(i), newValue);}/*** Atomically sets the element at position {@code i} to the given* updated value if the current value {@code ==} the expected value.** @param i the index* @param expect the expected value* @param update the new value* @return {@code true} if successful. False return indicates that* the actual value was not equal to the expected value.*/public final boolean compareAndSet(int i, int expect, int update) {return compareAndSetRaw(checkedByteOffset(i), expect, update);}private boolean compareAndSetRaw(long offset, int expect, int update) {return unsafe.compareAndSwapInt(array, offset, expect, update);}/*** Atomically sets the element at position {@code i} to the given* updated value if the current value {@code ==} the expected value.** <p><a href="package-summary.html#weakCompareAndSet">May fail* spuriously and does not provide ordering guarantees</a>, so is* only rarely an appropriate alternative to {@code compareAndSet}.** @param i the index* @param expect the expected value* @param update the new value* @return {@code true} if successful*/public final boolean weakCompareAndSet(int i, int expect, int update) {return compareAndSet(i, expect, update);}/*** Atomically increments by one the element at index {@code i}.** @param i the index* @return the previous value*/public final int getAndIncrement(int i) {return getAndAdd(i, 1);}/*** Atomically decrements by one the element at index {@code i}.** @param i the index* @return the previous value*/public final int getAndDecrement(int i) {return getAndAdd(i, -1);}/*** Atomically adds the given value to the element at index {@code i}.** @param i the index* @param delta the value to add* @return the previous value*/public final int getAndAdd(int i, int delta) {return unsafe.getAndAddInt(array, checkedByteOffset(i), delta);}/*** Atomically increments by one the element at index {@code i}.** @param i the index* @return the updated value*/public final int incrementAndGet(int i) {return getAndAdd(i, 1) + 1;}/*** Atomically decrements by one the element at index {@code i}.** @param i the index* @return the updated value*/public final int decrementAndGet(int i) {return getAndAdd(i, -1) - 1;}/*** Atomically adds the given value to the element at index {@code i}.** @param i the index* @param delta the value to add* @return the updated value*/public final int addAndGet(int i, int delta) {return getAndAdd(i, delta) + delta;}/*** Atomically updates the element at index {@code i} with the results* of applying the given function, returning the previous value. The* function should be side-effect-free, since it may be re-applied* when attempted updates fail due to contention among threads.** @param i the index* @param updateFunction a side-effect-free function* @return the previous value* @since 1.8*/public final int getAndUpdate(int i, IntUnaryOperator updateFunction) {long offset = checkedByteOffset(i);int prev, next;do {prev = getRaw(offset);next = updateFunction.applyAsInt(prev);} while (!compareAndSetRaw(offset, prev, next));return prev;}/*** Atomically updates the element at index {@code i} with the results* of applying the given function, returning the updated value. The* function should be side-effect-free, since it may be re-applied* when attempted updates fail due to contention among threads.** @param i the index* @param updateFunction a side-effect-free function* @return the updated value* @since 1.8*/public final int updateAndGet(int i, IntUnaryOperator updateFunction) {long offset = checkedByteOffset(i);int prev, next;do {prev = getRaw(offset);next = updateFunction.applyAsInt(prev);} while (!compareAndSetRaw(offset, prev, next));return next;}/*** Atomically updates the element at index {@code i} with the* results of applying the given function to the current and* given values, returning the previous value. The function should* be side-effect-free, since it may be re-applied when attempted* updates fail due to contention among threads.  The function is* applied with the current value at index {@code i} as its first* argument, and the given update as the second argument.** @param i the index* @param x the update value* @param accumulatorFunction a side-effect-free function of two arguments* @return the previous value* @since 1.8*/public final int getAndAccumulate(int i, int x,IntBinaryOperator accumulatorFunction) {long offset = checkedByteOffset(i);int prev, next;do {prev = getRaw(offset);next = accumulatorFunction.applyAsInt(prev, x);} while (!compareAndSetRaw(offset, prev, next));return prev;}/*** Atomically updates the element at index {@code i} with the* results of applying the given function to the current and* given values, returning the updated value. The function should* be side-effect-free, since it may be re-applied when attempted* updates fail due to contention among threads.  The function is* applied with the current value at index {@code i} as its first* argument, and the given update as the second argument.** @param i the index* @param x the update value* @param accumulatorFunction a side-effect-free function of two arguments* @return the updated value* @since 1.8*/public final int accumulateAndGet(int i, int x,IntBinaryOperator accumulatorFunction) {long offset = checkedByteOffset(i);int prev, next;do {prev = getRaw(offset);next = accumulatorFunction.applyAsInt(prev, x);} while (!compareAndSetRaw(offset, prev, next));return next;}/*** Returns the String representation of the current values of array.* @return the String representation of the current values of array*/public String toString() {int iMax = array.length - 1;if (iMax == -1)return "[]";StringBuilder b = new StringBuilder();b.append('[');for (int i = 0; ; i++) {b.append(getRaw(byteOffset(i)));if (i == iMax)return b.append(']').toString();b.append(',').append(' ');}}}

AtomicIntegerArray方法测试

package javalearn.javabase.thread.atomic;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.atomic.AtomicIntegerArray;
@Slf4j
public class AtomicIntegerArrTest {public static void main(String[] args) {int [] arr1 = new int[]{10,20,30,40};AtomicIntegerArray integerArray =new AtomicIntegerArray(arr1);for(int i= 0;i<arr1.length;i++){log.info("init arr [{}] is {}",i,integerArray.get(i));log.info("decrementAndGet arr[{}] is {}",i,integerArray.decrementAndGet(i));log.info("getAndIncrement arr[{}] is {}",i,integerArray.getAndIncrement(i));log.info("compareAndSet arr[{}] is {}",i,integerArray.compareAndSet(i,10,100));log.info("addAndGet 5 arr[{}] is {}",i,integerArray.addAndGet(i,5));}}
}

测试结果

12:39:09.205 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - init arr [0] is 10
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - decrementAndGet arr[0] is 9
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - getAndIncrement arr[0] is 9
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - compareAndSet arr[0] is true
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - addAndGet 5 arr[0] is 105
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - init arr [1] is 20
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - decrementAndGet arr[1] is 19
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - getAndIncrement arr[1] is 19
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - compareAndSet arr[1] is false
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - addAndGet 5 arr[1] is 25
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - init arr [2] is 30
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - decrementAndGet arr[2] is 29
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - getAndIncrement arr[2] is 29
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - compareAndSet arr[2] is false
12:39:09.216 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - addAndGet 5 arr[2] is 35
12:39:09.217 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - init arr [3] is 40
12:39:09.217 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - decrementAndGet arr[3] is 39
12:39:09.217 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - getAndIncrement arr[3] is 39
12:39:09.217 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - compareAndSet arr[3] is false
12:39:09.217 [main] INFO javalearn.javabase.thread.atomic.AtomicIntegerArrTest - addAndGet 5 arr[3] is 45

转载于:https://www.cnblogs.com/JuncaiF/p/11297875.html

java并发AtomicIntegerArray相关推荐

  1. Java并发AtomicIntegerArray类

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

  2. Java并发编程73道面试题及答案——稳了

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户 ...

  3. Java并发编程题库

    文章目录 并发编程三要素? 实现可见性的方法有哪些? 创建线程的有哪些方式? 创建线程的三种方式的对比? Runnable 和 Callable 的区别 Java线程具有五中基本状态 什么是线程池?有 ...

  4. 多线程面试题_100多线程和Java并发面试问答–最终清单(PDF下载)

    多线程面试题 在这篇文章中,我们将提供有关多线程和Java并发面试问答的综合文章. 编者注:并发始终是开发人员的挑战,编写并发程序可能非常困难. 引入并发时,有很多事情可能会崩溃,并且系统的复杂性会大 ...

  5. Java并发编程,无锁CAS与Unsafe类及其并发包Atomic

    为什么80%的码农都做不了架构师?>>>    我们曾经详谈过有锁并发的典型代表synchronized关键字,通过该关键字可以控制并发执行过程中有且只有一个线程可以访问共享资源,其 ...

  6. Java并发编程75道面试题及答案

    1.在java中守护线程和本地线程区别?java中的线程分为两种:守护线程(Daemon)和用户线程(User).任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon(bo ...

  7. Java 并发编程73道面试题及答案 ——面试看这篇就够了!

    作者:乌枭 https://blog.csdn.net/qq_34039315/article/details/78549311 1.在java中守护线程和本地线程区别? java中的线程分为两种:守 ...

  8. Java并发知识总结,超详细!(下)

    接着来~ 原子类 基本类型原子类 使用原子的方式更新基本类型 AtomicInteger:整型原子类 AtomicLong:长整型原子类 AtomicBoolean :布尔型原子类 AtomicInt ...

  9. Java并发编程面试题(2020最新版)

    转载自  Java并发编程面试题(2020最新版) 基础知识 并发编程的优缺点 为什么要使用并发编程(并发编程的优点) 充分利用多核CPU的计算能力:通过并发编程的形式可以将多核CPU的计算能力发挥到 ...

最新文章

  1. JVM内存调优原则及几种JVM内存调优方法
  2. 配置Cesium编译环境
  3. 基于Xml 的IOC 容器-向容器注册
  4. 开学了,也要开始找工作了
  5. 安装你自己的perl modules
  6. java8返回单个号码_如何在单个API中支持Java 6、8、9
  7. 查看ie保存的表单_解决浏览器保存密码自动填充问题
  8. 同一台服务器上部署多个Tomcat的配置修改方法
  9. 子盒子width为父盒子width的百分比注意
  10. Anaconda3创建、删除虚拟环境(win10)
  11. android view
  12. Word Clock数字时钟动态屏保,让你的电脑锁屏瞬间科技感十足!
  13. mac air 分区以后 分区内存消失了
  14. 项目管理软件推荐:项目计划变更管理太方便了
  15. 使用fastdfs上传视频并使用FFmpegFrameGrabberFrameGrabber在上传视频时截图作为封面
  16. python爬取微博图片教程_python实现爬取微博相册所有图片
  17. 债居时代总结与读后感——房贷如何影响经济[美]阿蒂夫·迈恩 [美]阿米尔·苏非著
  18. SpringBoot项目实现多数据源的三种方式
  19. Quasi_Binary(模拟)
  20. photoshop安装_如何在Photoshop中安装画笔

热门文章

  1. 当包装类的要与基本类型进行比较时候 需要先将包装类降级为基本类型
  2. EntityFramework Core 学习笔记 —— 包含与排除类型
  3. iOS多线程之GCD小记
  4. 超外差和超再生模块有何区别?
  5. 采集练习(七) php 获得电视节目预告(一周节目)
  6. (22)Xilinx FPGA开发软件chipscope(FPGA不积跬步101)
  7. (18)FPGA时序逻辑与组合逻辑(第4天)
  8. (41)System Verilog 例化System Verilog模块
  9. mysql存储引擎 索引优化_MySQL存储引擎,索引及基本优化策略
  10. 计算机专业排版有哪些,计算机专业英语词汇(完美排版_大容量打印版).pdf