在jdk>=1.5提供了atomic原子数据类,其目的就是方便多线程,无锁简单地进行原子操作
大概分为4类:
变量类:AtomicBoolean,AtomicInteger,AtomicLong,AtomicRefrence
数组类:AtomicIntergerArray,AtomicLongArray,AtomicRefreceArray
更新器类:AtomicLongFeildUpdater,AtomicIntegerFieldUpdater,AtomRefrenceFiledUpdater
复合变量类:AtomicaMarkableRefrence,AtomicStampedRefrence
变量类有很多方法,以AtomicInteger为例:
get() | 获取原子变量的值 |
incrementAndGet() | +1操作 并返回操作后的值 |
addAndGet(int value) | +value操作,并返回操作后的值 |
compareAndSet(int expect, int update) |
==? |
lazySet(int newValue) |
重置其值 |
例子:
package com.example; import com.example.utils.LogUtils; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; /** * @author xuanyouwu * @email xuanyouwu@163.com * @time 2016-05-04 14:03 */ public class AtomicClass { public static void main(String[] args) throws Exception { AtomicInteger atomicInteger=new AtomicInteger(); LogUtils.d("--------->incrementAndGet:"+atomicInteger.incrementAndGet()); LogUtils.d("--------->get:"+atomicInteger.get()); LogUtils.d("--------->addAndGet:"+atomicInteger.addAndGet(5)); LogUtils.d("--------->compareAndSet:"+atomicInteger.compareAndSet(6,atomicInteger.get())); LogUtils.d("--------->compareAndSet:"+atomicInteger.compareAndSet(5,atomicInteger.get())); atomicInteger.lazySet(100); LogUtils.d("--------->get:"+atomicInteger.get()); } }
--------->incrementAndGet:1
--------->get:1
--------->addAndGet:6
--------->compareAndSet:true
--------->compareAndSet:false
--------->get:100
数组类原子更新:
get(int index) | 获取指定索引位置的数据 |
addAndGet(int i, int delta) |
给指定索引位置数据增加delta |
incrementAndGet(int i) |
指定所有位置索引自增 |
例子:
int[] arr={0}; AtomicIntegerArray atomicIntegerArray=new AtomicIntegerArray(arr); LogUtils.d("-------->get:"+ atomicIntegerArray.get(0)); LogUtils.d("-------->addAndGet:"+ atomicIntegerArray.addAndGet(0,1)); LogUtils.d("-------->incrementAndGet:"+ atomicIntegerArray.incrementAndGet(0));
-------->get:0
-------->addAndGet:1
-------->incrementAndGet:2
原子更新引用类型:
User user=new User("xiaoming",new Random().nextInt(100)); LogUtils.d("------>user:"+user); AtomicReference<User> userAtomicReference=new AtomicReference<>(); userAtomicReference.set(user); userAtomicReference.updateAndGet(new UnaryOperator<User>() { @Override public User apply(User user) { user.age=user.age+1; return user; } }); LogUtils.d("------>updateAndGet:"+userAtomicReference.get());运行结果:
------>user:User{name='xiaoming', age=2}
------>updateAndGet:User{name='xiaoming', age=3}
原子更新字段
更新的字段必须使用public volatile修身符
User user=new User("xiaoming",new Random().nextInt(100)); LogUtils.d("------>user:"+user); AtomicIntegerFieldUpdater<User> userAtomicIntegerFieldUpdater=AtomicIntegerFieldUpdater.newUpdater(User.class,"age"); LogUtils.d("------>incrementAndGet:"+userAtomicIntegerFieldUpdater.incrementAndGet(user)); LogUtils.d("------>user:"+user);
运行结果:
------>user:User{name='xiaoming', age=62}
------>incrementAndGet:63
------>user:User{name='xiaoming', age=63}