第三章-原子类AtomicInteger-ABA问题

是什么

image-20191107103120391

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
static AtomicReference<Integer> atomicReference = new AtomicReference<>(100);
private static void atomicReferenceABA() {
new Thread(() -> {
atomicReference.compareAndSet(100, 101);
atomicReference.compareAndSet(101, 100);
}, "t1").start();
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(atomicReference.compareAndSet(100, 2019) + "\t" + atomicReference.get());
}, "t2").start();
}

public static void main(String[] args) {
// 基础版
atomicReferenceABA();
}

如何解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public static void main(String[] args) {
// 改良版
atomicStampedReferenceABA();
}

static AtomicStampedReference<Integer> atomicReference2 = new AtomicStampedReference<>(100, 1);
private static void atomicStampedReferenceABA() {
new Thread(() -> {
atomicReference2.compareAndSet(100, 101, 1, atomicReference2.getStamp()+1);
atomicReference2.compareAndSet(101, 100, 2, atomicReference2.getStamp()+1);
}, "t1").start();
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(atomicReference2.compareAndSet(100, 2019, 1, atomicReference2.getStamp()+1) + "\t" + atomicReference.get() + "\t" + atomicReference2.getStamp());
}, "t2").start();
}