AtomicInteger
众所周知,AtomicInteger用于多线程下线程安全的数据读写操作,避免使用锁同步,底层采用CAS实现,内部的存储值使用volatile修饰,因此多线程之间是修改可见的。
1. 构造
public AutomicInteger(int initValue): 有参构造,初始化为initValue
public AutomicInteger(): 无参构造,相当于AutomicInteger(0)
2. 自增1
public int getAndIncrement(): 返回当前值,并自增1
AtomicInteger ai = new AtomicInteger(5);
ai.getAndIncrement(); *// 5*
ai.get(); // 6
public int incrementAndGet(): 先自增1,再返回自增后的值
AtomicInteger ai = new AtomicInteger(5);
ai.incrementAndGet(); *// 6*
ai.get(); // 6
3. 自减1
public int getAndDecrement(): 返回当前值,并自减1
AtomicInteger ai = new AtomicInteger(5);
ai.getAndDecrement(); // 5
ai.get(); // 4
public int decrementAndGet(): 自减1, 返回自减后的值
AtomicInteger ai = new AtomicInteger(5);
ai.decrementAndGet(); // 4
ai.get(); // 4
4. 如果原来是A,则更新成B
public boolean compareAndSet(int source, int dest):source是改之前的值,Dest是改之后的值,source与当前真实值匹配了才能执行成功,返回值表示是否执行成功。
AtomicInteger ai = new AtomicInteger(10);
ai.compareAndSet(100, 12); // false, 因为改之前不是100
ai.get(); // 10ai.compareAndSet(10, 12); // true
ai.get(); // 12
5. 自增/自减N
public int getAndAdd(int delta): 先获取当前值,再进行计算val = val + delta
AtomicInteger ai = new AtomicInteger(10);
ai.getAndAdd(2); // 10ai.get(); // 12
public int addAndGet(int delta): 先计算 val = val + delta,再返回最新值
AtomicInteger ai = new AtomicInteger(10);
ai.addAndGet(2); // 12ai.get(); // 12
当然,这个方法也支持负数参数,也就意味着可以做减法
AtomicInteger ai = new AtomicInteger(5);
System.out.println(ai.addAndGet(-1)); // 4
6. 硬编码的二元计算逻辑
public int getAndUpdate (IntUnaryOperator opeartion): 使用lambda表达式进行二元运算,获取到的是旧值。
AtomicInteger ai = new AtomicInteger(10);
ai.getAndUpdate(x -> x + 2); // 10, oldVal
ai.get(); // 12
public int updateAndGet (IntUnaryOperator opeartion): 使用lambda表达式进行二元运算,获取到的是新值。
AtomicInteger ai = new AtomicInteger(10);
ai.updateAndGet(x -> x + 2); // 12, newVal
ai.get(); // 12
当然,这里支持减法也同样没问题
AtomicInteger ai = new AtomicInteger(5);
System.out.println(ai.updateAndGet(val -> val - 1)); // 4
7. 非硬编码的二元运算逻辑
public int getAndAccumulate(int factor, IntBinaryOperator operation): 先返回旧值,再进行计算
AtomicInteger ai = new AtomicInteger(10);
int result = ai.getAndAccumulate(5, new IntBinaryOperator() {@Override public int applyAsInt(int left, int right){ return left + right; } }); // result = 10, 旧值 ai.get(); // 15新值
public int accumulateAndGet(int factor, IntBinaryOperator operation): 先计算,再返回新值
AtomicInteger ai = new AtomicInteger(10);
int result = ai.accumulateAndGet(5, Integer::sum); // 15
ai.get(); // 15
同样,这个方法的自由度大大提高
int val = -1;
AtomicInteger ai = new AtomicInteger(5);
System.out.println(ai.accumulateAndGet(val, (a, b)-> b-a)); // -6
8. 直接赋值
public void set(int newVal): 直接更新为新值,区别于compareAndSet需要比对旧值。
9. 直接取值
public int get(): 取最新值
附:
底层的CAS是操作系统级别的实现:
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
自旋式乐观锁实现数值更新
public final int getAndAddInt(Object object, long valueOffset, int delta) {
int currentValue; do { currentValue= this.getIntVolatile(object, valueOffset); } while(!this.compareAndSwapInt(object, valueOffset, currentValue, currentValue + delta)); return currentValue; }
文章知识点与官方知识档案匹配,可进一步学习相关知识