根据修改的数据类型,可以将JUC包中的原子操作类可以分为4类。
1. 基本类型: AtomicInteger, AtomicLong, AtomicBoolean ;
2. 数组类型: AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray ;
3. 引用类型: AtomicReference, AtomicStampedRerence, AtomicMarkableReference ;
4. 对象的属性修改类型: AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater 。
这些类存在的目的是对相应的数据进行原子操作。所谓原子操作,是指操作过程不会被中断,保证数据操作是以原子方式进行的
概要
AtomicInteger, AtomicLong和AtomicBoolean这3个基本类型的原子类的原理和用法相似。本章以AtomicLong对基本类型的原子类进行介绍。内容包括:
AtomicLong介绍和函数列表
AtomicLong源码分析(基于JDK1.7.0_40)
AtomicLong示例
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3514593.html
AtomicLong介绍和函数列表
AtomicLong是作用是对长整形进行原子操作。
在32位操作系统中,64位的long 和 double 变量由于会被JVM当作两个分离的32位来进行操作,所以不具有原子性。而使用AtomicLong能让long的操作保持原子型。
AtomicLong函数列表
AtomicLong源码分析(基于JDK1.7.0_40)
AtomicLong的完整源码
AtomicLong的代码很简单,下面仅以incrementAndGet()为例,对AtomicLong的原理进行说明。
incrementAndGet()源码如下:
说明:
(01) incrementAndGet()首先会根据get()获取AtomicLong对应的long值。该值是volatile类型的变量,get()的源码如下:
// value是AtomicLong对应的long值
privatevolatilelong value;
// 返回AtomicLong对应的long值
publicfinallong get() {
return value; }
(02) incrementAndGet()接着将current加1,然后通过CAS函数,将新的值赋值给value。
compareAndSet()的源码如下:
public final boolean compareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
compareAndSet()的作用是更新AtomicLong对应的long值。它会比较AtomicLong的原始值是否与expect相等,若相等的话,则设置AtomicLong的值为update。
AtomicLong示例
运行结果:
概要
AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray这3个数组类型的原子类的原理和用法相似。本章以AtomicLongArray对数组类型的原子类进行介绍。内容包括:
AtomicLongArray介绍和函数列表
AtomicLongArray源码分析(基于JDK1.7.0_40)
AtomicLongArray示例
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3514604.html
AtomicLongArray介绍和函数列表
在"Java多线程系列--“JUC原子类”02之 AtomicLong原子类"中介绍过,AtomicLong是作用是对长整形进行原子操作。而AtomicLongArray的作用则是对"长整形数组"进行原子操作。
AtomicLongArray函数列表
AtomicLongArray源码分析(基于JDK1.7.0_40)
AtomicLongArray的代码很简单,下面仅以incrementAndGet()为例,对AtomicLong的原理进行说明。
incrementAndGet()源码如下:
publicfinallong incrementAndGet(int i) { return addAndGet(i, 1); }
说明:incrementAndGet()的作用是以原子方式将long数组的索引 i 的元素加1,并返回加1之后的值。
addAndGet()源码如下:
publiclong addAndGet(int i, long delta) { // 检查数组是否越界long offset = checkedByteOffset(i); while (true) { // 获取long型数组的索引 offset 的原始值long current = getRaw(offset); // 修改long型值long next = current + delta; // 通过CAS更新long型数组的索引 offset的值。if (compareAndSetRaw(offset, current, next)) return next; } }
说明:addAndGet()首先检查数组是否越界。如果没有越界的话,则先获取数组索引i的值;然后通过CAS函数更新i的值。
getRaw()源码如下:
privatelong getRaw(long offset) { return unsafe.getLongVolatile(array, offset); }
说明:unsafe是通过Unsafe.getUnsafe()返回的一个Unsafe对象。通过Unsafe的CAS函数对long型数组的元素进行原子操作。如compareAndSetRaw()就是调用Unsafe的CAS函数,它的源码如下:
privateboolean compareAndSetRaw(long offset, long expect, long update) { return unsafe.compareAndSwapLong(array, offset, expect, update); }
AtomicLongArray示例
1// LongArrayTest.java的源码 2import java.util.concurrent.atomic.AtomicLongArray; 3 4publicclass LongArrayTest { 5 6publicstaticvoid main(String[] args){ 7 8// 新建AtomicLongArray对象 9long[] arrLong = newlong[] {10, 20, 30, 40, 50}; 10 AtomicLongArray ala = new AtomicLongArray(arrLong); 1112 ala.set(0, 100); 13for (int i=0, len=ala.length(); i<len; i++) 14 System.out.printf("get(%d) : %s\n", i, ala.get(i)); 1516 System.out.printf("%20s : %s\n", "getAndDecrement(0)", ala.getAndDecrement(0)); 17 System.out.printf("%20s : %s\n", "decrementAndGet(1)", ala.decrementAndGet(1)); 18 System.out.printf("%20s : %s\n", "getAndIncrement(2)", ala.getAndIncrement(2)); 19 System.out.printf("%20s : %s\n", "incrementAndGet(3)", ala.incrementAndGet(3)); 2021 System.out.printf("%20s : %s\n", "addAndGet(100)", ala.addAndGet(0, 100)); 22 System.out.printf("%20s : %s\n", "getAndAdd(100)", ala.getAndAdd(1, 100)); 2324 System.out.printf("%20s : %s\n", "compareAndSet()", ala.compareAndSet(2, 31, 1000)); 25 System.out.printf("%20s : %s\n", "get(2)", ala.get(2)); 26 } 27 }
运行结果:
get(0) : 100 get(1) : 20 get(2) : 30 get(3) : 40 get(4) : 50 getAndDecrement(0) : 100 decrementAndGet(1) : 19 getAndIncrement(2) : 30 incrementAndGet(3) : 41 addAndGet(100) : 199 getAndAdd(100) : 19 compareAndSet() : true get(2) : 1000
Java多线程系列--“JUC原子类”04之 AtomicReference原子类
http://www.cnblogs.com/skywang12345/p/3514623.html