java并发AtomicIntegerArray
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的更多相关文章
- Java并发AtomicIntegerArray类
java.util.concurrent.atomic.AtomicIntegerArray类提供了可以以原子方式读取和写入的底层int数组的操作,还包含高级原子操作. AtomicIntegerAr ...
- JAVA并发编程J.U.C学习总结
前言 学习了一段时间J.U.C,打算做个小结,个人感觉总结还是非常重要,要不然总感觉知识点零零散散的. 有错误也欢迎指正,大家共同进步: 另外,转载请注明链接,写篇文章不容易啊,http://www. ...
- Java并发编程-总纲
Java 原生支持并发,基本的底层同步包括:synchronized,用来标示一个方法(普通,静态)或者一个块需要同步执行(某一时刻,只允许一个线程在执行代码块).volatile,用来标识一个变量是 ...
- Java并发编程深入学习
上周的面试中,被问及了几个并发开发的问题,自己回答的都不是很系统和全面,可以说是"头皮发麻",哈哈.因此果断购入<Java并发编程的艺术>一书,该书内容主要是对ifev ...
- Java并发编程75道面试题及答案
1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon( ...
- java并发编程知识点备忘
最近有在回顾这方面的知识,稍微进行一些整理和归纳防止看了就忘记. 会随着进度不断更新内容,比较零散但尽量做的覆盖广一点. 如有错误烦请指正~ java线程状态图 线程活跃性问题 死锁 饥饿 活锁 饥饿 ...
- Java并发编程75个问答
1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线程(Daemon)和用户线程(User). 任何线程都可以设置为守护线程和用户线程,通过方法Thread.setDaemon( ...
- Java并发编程73道面试题及答案
原文出处:https://blog.csdn.net/qq_34039315/article/details/7854931 1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线 ...
- Java并发编程快速学习
上周的面试中,被问及了几个关于Java并发编程的问题,自己回答的都不是很系统和全面,可以说是"头皮发麻",哈哈.因此果断购入<Java并发编程的艺术>一书,学习后的体会 ...
随机推荐
- CSS-禁止文本被选中
pc端: .not-select{ -moz-user-select:none; /*火狐*/ -webkit-user-select:none; /*webkit浏览器*/ -ms-user-sel ...
- Django - Form嵌套的Meta类 + 为什么type()能创建类
Form里面嵌套了一个Meta类 class PostForm(forms.ModelForm): class Meta: model = Post # field to be exposed fie ...
- 网络基础:ARP 协议、IP协议、路由协议 均属于网络层协议
ARP协议 ARP--地址解析协议(Address Resolution Protocol),实现通过 对方的IP地址(域名) 寻找对方的 MAC地址 ARP的功能 本地电脑查看 IP 和 MAC 对 ...
- BeautifulReport底层框架的解析以及html报告页面元素的更改
利用BeautifulReport 模块生成html报告 import BeautifulReport as br#引入包,之后设置一下别名 br = br.BeautifulReport(test_ ...
- 卸载mysql时,提示libmysqlclient.so.16()(64bit) is needed by (installed) postfix
卸载时,提示错误,用这个命令就可以rpm -e --nodeps mysql-libs-5.1.73-5.el6_6.x86_64(这个是自己要卸载的版本) [root@unaryhost dev]# ...
- Spring Boot FreeMarker 使用教程
FreeMarker 跟 Thymeleaf 一样,是一种模板引擎,他可以无缝兼容 FreeMarker 在 Spring Boot 开发者中仍然有着很高的地位. 本章重点内容 编写一个最简单的 Fr ...
- Spring Boot 定时任务 Quartz 使用教程
Quartz是一个完全由java编写的开源作业调度框架,他使用非常简单.本章主要讲解 Quartz在Spring Boot 中的使用. 快速集成 Quartz 介绍 Quartz 几个主要技术点 Qu ...
- python调用os模块锁定用户
import timeimport osuser_info = { 'mac': {'pwd': '123', 'count': 0, 'locked': False}, 'tank': {'pwd' ...
- [01]Binary Search二分查找
Binary Search二分查找 作用:二分查找适用于有序的的数组或列表中,如果列表及数组中有n个元素,通过二分查找查询某一元素的位置需要的步骤是log2(n)(注:该log的底数是2) 1.Pyt ...
- 第二节: Vuejs常用特性1
一. 常用特性 1. 表单元素 通过 v-model指令绑定 输入框.单选/多选框.下拉框.文本框 2. 表单域修饰符 (1) .number:转换成数值,如果输入的是非数字字符串时,无法进行转换 ( ...