版权声明:欢迎转载,转载请说明出处. 大数据Github项目地址https://github.com/SeanYanxml/bigdata。 https://blog.csdn.net/u010416101/article/details/88678305
前言
在前四个模块中,我们主要介绍了Thread类、synchronized与volatile关键字、线程通信、ReentrantLock锁. 本节我们将介绍Java中的原子操作.
本章主要包括如下几个部分:
- 原子更新基本类型
- 原子更新数组
- 原子更新引用类型
- 原子更新字段类
正文
原子更新基本类型
- AtomicBoolean
- AtomicInteger
- AtomicLong
// Integer类型
public static void methodA(){
AtomicInteger atomicInteger = new AtomicInteger(1);
System.out.println(atomicInteger.get());
System.out.println(atomicInteger.incrementAndGet());
}
// methodA
// 1
// 2
原子更新数组
- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray
AtomicIntegerArray类
中主要有两个方法
int addAndGet(int i, int delta)
原子方式将输入值与数组中索引为i的元素相加;compareAndSwap(int i, int expect,int update)
如果当前值等于预期值,则以原子方式将数组位置i的元素设置为update的值.
public static void methodB(){
int []value = {1,2};
AtomicIntegerArray atomicArray = new AtomicIntegerArray(value);
atomicArray.getAndSet(0, 3);
System.out.println(atomicArray.get(0));
System.out.println(value[0]);
}
// methodB
// 3
// 1
原子更新引用类型
- AtomicReference
- AtomicReferenceFieldUpdater
- AtomicMarkableReference(尚未研究)
class User{
private String name;
private int old;
public User(String name,int old){
this.name = name;
this.old = old;
}
public String getName(){
return name;
}
public int getOld(){
return old;
}
}
public static void methodC(){
User sean = new User("Sean", 24);
AtomicReference<User> atomicUserRef = new AtomicReference<User>();
atomicUserRef.set(sean);
User abel = new User("Abel", 25);
atomicUserRef.compareAndSet(sean, abel);
System.out.println(atomicUserRef.get().getName());
System.out.println(atomicUserRef.get().getOld());
}
// methodC
// Abel
// 25
原子更新字段类
- AtomicIntegerFieldUpdater
- AtomicLongFieldUpdater
- AtomicStampedReference: 使用版本号解决CAS中可能出现的ABA问题.
public static void methodD(){
AtomicIntegerFieldUpdater<User> atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(User.class, "old");
User abel = new User("abel", 25);
System.out.println(atomicIntegerFieldUpdater.getAndIncrement(abel));
System.out.println(atomicIntegerFieldUpdater.get(abel));
}
// methodD
// Abel
// 25
CAS机制与问题
CAS机制
CAS 即 Compare and Swap. 其在原子类与锁中使用广泛.
public final getAndIncrement(){
for(;;){
int current = get();
int next = current+1;
if(compareAndSwap(current, next))
return current;
}
}
public final boolean compareAndSet(int expect, int update){
return unsafe.compareAndSwapInt(this, valueoffset, expect, update);
}
在unsafe
中是通过native
方法调用linux指令进行完成的.
面试必问的CAS,你懂了吗?
Java中的CAS实现原理
漫画:什么是 CAS 机制?
问题
- 循环时间开销大
- 只能完成单个的原子的操作
- ABA问题
Reference
[1]. Java 多线程编程核心技术
[2]. Java并发编程的艺术
[3]. 面试必问的CAS,你懂了吗?
[4]. Java中的CAS实现原理
[5]. 漫画:什么是 CAS 机制?
[6]. Java多线程系列–“JUC原子类”01之 框架