Skip to content

Commit 4b46e2e

Browse files
committed
Update Atomic.md
1 parent 0ad4e23 commit 4b46e2e

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

docs/java/Multithread/Atomic.md

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)