Java线程中的java.util.concurrent.atomic包里面都是类都是针对多线程下的原子变量,有包括AtomicInteger, AtomicBoolean等等多种变量的原子化实现。java
本次咱们将会解读AtomicInteger的源码,对变量的原子化思路进行一个理解。这也会对理解现实场景中,多线程程序原子化使用某个资源也有更好的理解。咱们抽取几个主要的方法进行解读。数据库
AtomicInteger主要实现了Number接口,这个接口提供的方法都是将原子变量值转换为其余类型值的接口。多线程
而主要的原子化特性则是经过持有jdk.internal.misc.Unsafe对象实现Proxy模式进行实现。函数
两个静态变量十分清晰:atom
Uspa
是调用了jdk.internal.misc.Unsafe对象,协助后面的原子性更新特性。
VALUE线程
则是使用了objectFieldOffset获取了对象在JVM内存中的地址。该方法的具体实现则是一个native方法,经过C或C++对JVM内部进行操做。暂时不做细究。
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe(); private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value"); private volatile int value;
构造函数
AtomicInteger(int)code
将传入int值,写入为成员变量,令对象持有该值。
主要API及源码解读对象
int get()接口
比较直观的实现,直接返回被声明为volatile的value。
void set(int)
比较直观的实现,将输入值赋值到为volatile的value。
int getAndIncrement()
有效的逻辑,在调用Unsafe对象的下面两个方法:
public final int getAndAddInt(Object o, long offset, int delta) { int v; do {// 循环 // getIntVolatile是一个native方法: // 之内存地址,及Object对象肯定获取内存中的volatile值 v = getIntVolatile(o, offset); } while (!weakCompareAndSetInt(o, offset, v, v + delta)); //调用下方的weakCompareAndSetInt方法,直到更新成功则退出循环 return v; } public final boolean weakCompareAndSetInt(Object o, long offset, int expected, int x) { // 调用native方法compareAndSetInt // 以对象类型o,内存地址offset,指望值expected,输入值x // 按照对象类型及内存地址得到期待值,对比后更新为输入值。 return compareAndSetInt(o, offset, expected, x); }
int getAndDecrement()
相似于getAndIncreement,调用Unsafe,对内存中数值进行操做。
经过回顾针对AtomiInteger的几个基本方法原子化操做的解读,咱们能够理解为原子操做的几个要点:
对于数据库记录的原子性的解决方案,也有相似的解决方案,多线程占用某个数据库资源更新时,咱们也能够先作读取,核对值或版本号后再做更新。
对于数据库相关的原子性保证更新,咱们下一篇再聊聊。