JUC-原子操作类总结

JUC-原子操作类总结

怎么理解呢
原子性表示一个或者多个操作,要么全部执行完,要么一个也不执行。不能出现成功一部分失败一部分的情况。
典型的原子性问题
在多线程中,如果多个线程同时更新一个共享变量,可能会得到一个意料之外的值。比如 i=1 。A 线程更新 i+1 、B 线程也更新 i+1。通过两个线程并行操作之后可能 i 的值不等于 3。而可能等于 2。因为 A 和 B 在更新变量 i 的时候拿到的 i 可能都是 1,这就是一个典型的原子性问题。
实现原子性

  1. 加 Synchronized 同步锁
  2. 从 JDK1.5 开始,在 J.U.C 包中提供了 Atomic包,提供了对于常用数据结构的原子操作。它提供了简单、高效、以及线程安全的更新一个变量的方式
    J.U.C 中的原子操作类
    由于变量类型的关系,在 J.U.C 中提供了 12 个原子操作的类。这 12 个类可以分为四大类
  3. 原子更新基本类型
    AtomicBoolean、AtomicInteger、AtomicLong
  4. 原子更新数组
    AtomicIntegerArray 、 AtomicLongArray 、AtomicReferenceArray
  5. 原子更新引用
    AtomicReference 、 AtomicReferenceFieldUpdater 、AtomicMarkableReference(更新带有标记位的引用类型)
  6. 原子更新字段
    AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicStampedReference

AtomicrInteger 原理分析

getAndIncrement()

public final int getAndIncrement() {
	return  unsafe.getAndAddInt(this,valueOffset, 1);
}

getAndIncrement 实际上是调用 unsafe 这个类里面提供的方法,Unsafe 类我们前面在分析 AQS 的时候讲过,这个类相当于是一个后门,使得 Java 可以像 C 语言的指针一样直接操作内存空间。当然也会带来一些弊端,就是指针的问题。实际上这个类在很多方面都有使用,除了 J.U.C 这个包以外,还有 Netty、kafka 等等,这个类提供了很多功能,包括多线程同步(monitorEnter)、CAS 操 作 (compareAndSwap) 、 线 程 的 挂 起 和 恢 复
(park/unpark)、内存屏障(loadFence/storeFence)内存管理(内存分配、释放内存、获取内存地址等.)
valueOffset参数

private static final long valueOffset;
static {
try {
	valueOffset = unsafe.objectFieldOffset
	(AtomicInteger.class.getDeclaredField("value"));
}  catch  (Exception  ex)  {  throw  new Error(ex); }
}

通过 unsafe.objectFieldOffset()获取当前 Value 这个变量在内存中的偏移量,也就是valueOffset,后续会基于valueOffset从内存中得到value的值来和当前的值做比较,实现乐观锁。

getAndAddInt()

public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
	var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2,var5, var5 + var4));
	return var5;
}

通过 do/while 循环,基于 CAS 乐观锁来做原子递增。实际上前面的 valueOffset 的作用就是从主内存中获得当前value 的值和预期值做一个比较,如果相等,对 value 做递增并结束循环。

get 方法

public final int get() {
	return value;
}

get 方法只需要直接返回 value 的值就行,这里的 value 是通过 Volatile 修饰的,用来保证可见性。
其他方法
AtomicInteger 的实现非常简单,所以我们可以很快就分析完它的实现原理,当然除了刚刚分析的这两个方法之外,还有其他的一些比 如 它 提 供 了 compareAndSet , 允 许 客 户 端 基 于AtomicInteger 来实现乐观锁的操作

public final boolean compareAndSet(int expect, int update) {
	return  unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值