背景:JDK8,对AtomicInteger包addAndGet(xxx)方法,CAS保证原子性的调试跟踪
执行代码如下:
模拟两个线程并发操作a做+1操作。
package com.ryan.practise.design.atomic;
import java.util.concurrent.atomic.AtomicInteger;
public class TestCase {
static AtomicInteger a = new AtomicInteger(13);
private static void test2() {
Thread t1 = new Thread(new InnerThread());
Thread t2 = new Thread(new InnerThread());
t1.start();
t2.start();
}
public static void main(String[] args) {
test2();
}
static class InnerThread implements Runnable{
@Override
public void run() {
int result = a.addAndGet(1);
System.out.println(result);
}
}
}
Thread0
Step1:Thread0与Thread1执行到相同位置,模拟并发场景。
Step3: Thead0执行CAS完成后 var1.value = 14,va1.value = var5 ,为最新值,Thread0执行+1操作。
Thread1
Step2: Thread1与Thread0执行到相同位置,模拟并发场景。
Step4:Thead0已经执行完+1操作,#362行代码,此时
- var1.value= 14,
- var5为Thread0未完成+1操作前获取的value值,猜想:var5为局部变量,+1操作分为:
- 取出value值,
- 对取出值+1
- var1.value值刷新为新值
1,2为非原子性操作,故有了do...while自旋,保证+1操作的原子性。
- 因为AtomicInteger value字段 由volidate修饰,value值的修改,保证所有线程可见,即Step3中,var1已经改变。循环中,始终是var1.value是var5在找相等,也是这两个值在持续改变
- var2为value字段偏移量,始终固定
- var4为传入参数,始终固定。
Step5:CAS -> false;继续循环,此时var1.value = 14, var5重新从var1获取到新值
Step6:var5重新赋值完毕,继续CAS判断,是否为var1最新value
Step7:va1.value = var5 ,为最新值,Thread1执行+1操作。