@@ -64,7 +64,56 @@ Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是
64
64
- AtomicIntegerFieldUpdater:原子更新整型字段的更新器
65
65
- AtomicLongFieldUpdater:原子更新长整型字段的更新器
66
66
- 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
+
68
117
69
118
** CAS ABA 问题**
70
119
- 描述: 第一个线程取到了变量 x 的值 A,然后巴拉巴拉干别的事,总之就是只拿到了变量 x 的值 A。这段时间内第二个线程也取到了变量 x 的值 A,然后把变量 x 的值改为 B,然后巴拉巴拉干别的事,最后又把变量 x 的值变为 A (相当于还原了)。在这之后第一个线程终于进行了变量 x 的操作,但是此时变量 x 的值还是 A,所以 compareAndSet 操作是成功。
0 commit comments