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 guarantees
this.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

java并发AtomicIntegerArray的更多相关文章

  1. Java并发AtomicIntegerArray类

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

  2. JAVA并发编程J.U.C学习总结

    前言 学习了一段时间J.U.C,打算做个小结,个人感觉总结还是非常重要,要不然总感觉知识点零零散散的. 有错误也欢迎指正,大家共同进步: 另外,转载请注明链接,写篇文章不容易啊,http://www. ...

  3. Java并发编程-总纲

    Java 原生支持并发,基本的底层同步包括:synchronized,用来标示一个方法(普通,静态)或者一个块需要同步执行(某一时刻,只允许一个线程在执行代码块).volatile,用来标识一个变量是 ...

  4. Java并发编程深入学习

    上周的面试中,被问及了几个并发开发的问题,自己回答的都不是很系统和全面,可以说是"头皮发麻",哈哈.因此果断购入<Java并发编程的艺术>一书,该书内容主要是对ifev ...

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

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

  6. java并发编程知识点备忘

    最近有在回顾这方面的知识,稍微进行一些整理和归纳防止看了就忘记. 会随着进度不断更新内容,比较零散但尽量做的覆盖广一点. 如有错误烦请指正~ java线程状态图 线程活跃性问题 死锁 饥饿 活锁 饥饿 ...

  7. Java并发编程75个问答

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

  8. Java并发编程73道面试题及答案

    原文出处:https://blog.csdn.net/qq_34039315/article/details/7854931 1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线 ...

  9. Java并发编程快速学习

    上周的面试中,被问及了几个关于Java并发编程的问题,自己回答的都不是很系统和全面,可以说是"头皮发麻",哈哈.因此果断购入<Java并发编程的艺术>一书,学习后的体会 ...

随机推荐

  1. 计算机二级-C语言-程序设计题-190118记录-通过数组和指针两种方式对字符串进行处理。

    //编写一个函数fun,比较两个字符串的长度,(不使用C语言提供的求字符串长度的函数),函数返回较长的字符串.若两个字符长度相同,则返回第一个字符串. //重难点:通过数组处理和通过指针进行处理的不同 ...

  2. Computational Complexity of Fibonacci Sequence / 斐波那契数列的时空复杂度

    Fibonacci Sequence 维基百科 \(F(n) = F(n-1)+F(n-2)\),其中 \(F(0)=0, F(1)=1\),即该数列由 0 和 1 开始,之后的数字由相邻的前两项相加 ...

  3. Django框架中的Cookie和Session

    学习内容: (1)cookie (2)session Web是基于请求/响应模式,HTTP协议是无状态的,但是基于 Internet的各种服务系统应运而生,建立商业站点或者功能比较完善的个人站点,常常 ...

  4. list随机生成数值

    List<int> numbers = Enumerable.Range(5, 10).ToList();

  5. java 责任链模式的三种实现

    责任链模式 责任链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止.这里就不再过多的介绍什么 ...

  6. SprintBoot学习(三)

    Thymeleaf模板引擎 1.thymeleaf是一个Java类库,,他是xml/xhtml/html5的模板引擎可以作为view层 2.themeleaf基本语法 引入thymeleaf < ...

  7. Java面向对象编程 -1.3

    类与对象的定义与使用 在Java之中类是一个独立的结构体,所以需要使用class来进行定义,而类之中主要由属性和方法所组成,那么属性就是一个个具体的变量,方法就是可以重复执行的代码. 定义一个类 cl ...

  8. 与英特尔分道扬镳,苹果的5G业务掉队了吗?

    5G概念已经大热,越来越多的厂商推出相关产品,中国骄傲之华为不仅在5G通信标准制定方面参与感非常强,也先于竞争对手推出5G智能终端,连同三星/Vivo等也纷纷推出5G终端,而作为智能手机市场绝对的利润 ...

  9. [运维] 请求 nginx 出现 502 Bad Gateway 的解决方案!

    环境: 云服务器镜像 Linux CentOS 7.6 已经安装并成功配置 SSL 的 nginx 1.16.1 成功安装并且可以正常运行的 apache-tomcat-9.0.26 遇到的问题: 在 ...

  10. C/C++网络编程8——多进程服务器端之销毁僵尸进程

    上一节提到,当子进程执行结束,父进程还在执行,在父进程结束之前子进程会成为僵尸进程,那么怎么销毁僵尸进程呢?父进程主动接收子进程的返回值. 销毁僵尸进程的方法: 1:使用wait函数 2:使用wait ...