一、原子性操作方法
1.1 同步锁
synchronized (this){
++ count;
}
1.2 Atomic类
- Atomic底层利用CAS实现,而CAS则是利用UnSafe类(native) + 反射技术实现,通过
do...while(自旋)
的模式,每次都会检查变量是否被修改过,修改过则while成立并重做。
private AtomicLong acount = new AtomicLong(0L);
acount.incrementAndGet();
1.3 LongAdder类
- LongAdder为JDK8提供的多线程技术类,底层是利用分而治之的思想,即为每个线程分配一个计数副本,线程之间的副本相互隔离,最终将所有副本相加,多线程下计数速度最快。
private LongAdder lacount = new LongAdder();
// 计数
lacount.increment();
// 获取结果
lacount.sum()
二、Atomic类实现原理-CAS
-
- 通过
Unsafe
获取对象属性偏移量
- 通过
-
- 利用
Unsafe
的CMS方法及获取到的偏移量实现自增(操作内存)
- 利用
public class LockDemo1 {
private volatile int value = 0;
// 直接操作内存,修改对象、数组内存等
private static Unsafe unsafe;
// 获取属性偏移量
private static long valueOfferset;
static {
try {
//反射技术获取unsafe值
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = (Unsafe)field.get(null);
// 获取到value属性偏移量(用于定位value属性在内存中的具体地址)
valueOfferset = unsafe.objectFieldOffset(LockDemo1.class.getDeclaredField("value"));
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
public void add() {
// i++; 在Java层面分为三个步骤
// CAS + 循环重试(自旋)
int current;
do {
// 操作耗时的话线程会占用大量的CPU执行时间
current = unsafe.getIntVolatile(this, valueOfferset);
} while (!unsafe.compareAndSwapInt(this, valueOfferset, current, current + 1));
// 执行失败则重试
}
public static void main(String[] args) throws InterruptedException {
LockDemo1 lockDemo1 = new LockDemo1();
for (int i = 0; i < 2; i++) {
new Thread(() -> {
for (int j = 0; j < 10000; j++) {
lockDemo1.add();
}
}).start();
}
Thread.sleep(2000L);
System.out.println(lockDemo1.value);
}
}