@@ -64,7 +64,56 @@ Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是
6464- AtomicIntegerFieldUpdater:原子更新整型字段的更新器
6565- AtomicLongFieldUpdater:原子更新长整型字段的更新器
6666- AtomicStampedReference :原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于解决原子的更新数据和数据的版本号,可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。
67- - AtomicMarkableReference:原子更新带有标记的引用类型。该类将 boolean 标记与引用关联起来,也可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。
67+ - AtomicMarkableReference:原子更新带有标记的引用类型。该类将 boolean 标记与引用关联起来,~~ 也可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。~~
68+
69+ > 修正: ** AtomicMarkableReference 不能解决ABA问题**
70+
71+ ``` java
72+ /**
73+
74+ AtomicMarkableReference是将一个boolean值作是否有更改的标记,本质就是它的版本号只有两个,true和false,
75+
76+ 修改的时候在这两个版本号之间来回切换,这样做并不能解决ABA的问题,只是会降低ABA问题发生的几率而已
77+
78+ @author : mazh
79+
80+ @Date : 2020/1/17 14:41
81+ */
82+
83+ public class SolveABAByAtomicMarkableReference {
84+
85+ private static AtomicMarkableReference atomicMarkableReference = new AtomicMarkableReference (100 , false );
86+
87+ public static void main (String [] args ) {
88+
89+ Thread refT1 = new Thread (() - > {
90+ try {
91+ TimeUnit . SECONDS. sleep(1 );
92+ } catch (InterruptedException e) {
93+ e. printStackTrace();
94+ }
95+ atomicMarkableReference. compareAndSet(100 , 101 , atomicMarkableReference. isMarked(), ! atomicMarkableReference. isMarked());
96+ atomicMarkableReference. compareAndSet(101 , 100 , atomicMarkableReference. isMarked(), ! atomicMarkableReference. isMarked());
97+ });
98+
99+ Thread refT2 = new Thread (() - > {
100+ boolean marked = atomicMarkableReference. isMarked();
101+ try {
102+ TimeUnit . SECONDS. sleep(2 );
103+ } catch (InterruptedException e) {
104+ e. printStackTrace();
105+ }
106+ boolean c3 = atomicMarkableReference. compareAndSet(100 , 101 , marked, ! marked);
107+ System . out. println(c3); // 返回true,实际应该返回false
108+ });
109+
110+ refT1. start();
111+ refT2. start();
112+ }
113+ }
114+ ```
115+
116+
68117
69118** CAS ABA 问题**
70119- 描述: 第一个线程取到了变量 x 的值 A,然后巴拉巴拉干别的事,总之就是只拿到了变量 x 的值 A。这段时间内第二个线程也取到了变量 x 的值 A,然后把变量 x 的值改为 B,然后巴拉巴拉干别的事,最后又把变量 x 的值变为 A (相当于还原了)。在这之后第一个线程终于进行了变量 x 的操作,但是此时变量 x 的值还是 A,所以 compareAndSet 操作是成功。
0 commit comments