基础 | 并发编程 - [原子类]

§1 总览

原子类大多在包 java.util.concurrent.atomic 下

原子型基础型类型说明
AtomicBooleanboolean基本
AtomicIntegerint基本
AtomicIntegerArrayint[]数组
AtomicIntegerFieldUpdater
AtomicLonglong基本
AtomicLongArraylong[]数组
AtomicLongFieldUpdater
AtomicMarkableReference
AtomicReferenceObject引用
AtomicReferenceArrayObject[]数组
AtomicReferenceFieldUpdater
AtomicStampedReference
DoubleAccumulator
DoubleAdder
LongAccumulator
LongAdder

通用 api

  • get()
    获取
  • getAndSet()
    获取并赋予新值,相当于 i=x
  • getAndIncrement()
    获取并自增,相当于 i++
  • getAndDecrement()
    获取并自减,相当于 i--
  • getAndAdd()
    获取并在原值基础上 + 差值,相当于 i+=x
  • compareAndSet()
    比较,如果相等就赋予新值

§2 基本类型原子类

基础数据类型原子类

  • AtomicBoolean,相当于 boolean
  • AtomicInteger,相当于 int
  • AtomicLong,相当于 long

示例

AtomicInteger atomicInteger = new AtomicInteger(10);
atomicInteger.getAndIncrement();//相当于 i++

§3 数组类型原子类

数组数据类型原子类
类似 基础数据类型原子类

  • AtomicBooleanArray,相当于 boolean[]
  • AtomicIntegerArray,相当于 int[]
  • AtomicLongArray,相当于 long[]

§4 引用类型原子类

引用类型原子类

  • AtomicReference
    相当于 Object
    常用于实现基于线程的自旋锁
    不能处理 ABA 问题
  • AtomicStamptReference
    AtomicReference 增加了版本信息
    常用于实现基于线程的自旋锁
    可以处理 ABA 问题
  • AtomicMarkableReference
    AtomicReference 增加了修改标记
    修改值前,应判断修改标记 isMarked()
    修改值时,应同步修改 修改标记compareAndSet(old, new, oldMark, !oldMark)
    可以处理 ABA 问题,相对于 AtomicStamptReference 只关心是否被改过,而不关心更改次数

注意
引用类型原子类只能 CAS 引用本身,而不是引用内部的字段值

User user = new User();
AtomicReference<User> atomicUser = new AtomicReference<>();
atomicUser.set(user);
atomicUser.compareAndSet(user,new User());

§4 属性修改原子类

  • 用于对非线程安全的字段进行 线程安全 的修改
  • 基于反射实现
  • 被修改的字段必须被 public volatile 修饰

包含下面三个类

  • AtomicIntegerFieldUpdater
  • AtomicLongFieldUpdater
  • AtomicReferenceFieldUpdater
AtomicIntegerFieldUpdater<User> updater = 
	AtomicIntegerFieldUpdater.newUpdater(User.class,"age");

updater.getAndIncrement(user);

§5 原子操作增强

  • DoublAccumulator
  • DoubleAdder
  • LongAccumulator
  • LongAdder

应用场景
适用于不要求实时精确,的基础数据累加

  • 点赞计数器
  • int[] 所有元素 ++

AtomicLong 比较

  • 高并发场景下性能提高,减少 cas 消耗(大约一个数量级)
  • 不能保证实时精准

LongAdderLongAccumulator 的区别

初始值加值
LongAdder只能是 0只能是 1
LongAccumulator任意任意
LongAdder adder = new LongAdder();
adder.increment();
adder.increment();
System.out.println(adder.sum()); // 2

LongAccumulator accumulator = new LongAccumulator((x,y)->x+y,0);
accumulator.accumulate(1);
accumulator.accumulate(2);
System.out.println(accumulator.get()); // 3

源码
详见 基础 | 并发编程 - [Striped64]

§6 原子操作底层类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值