Update Atomic.md

This commit is contained in:
shuang.kou 2020-02-20 21:09:49 +08:00
parent 0ad4e236cb
commit 4b46e2eb23
1 changed files with 50 additions and 1 deletions

View File

@ -64,7 +64,56 @@ Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是
- AtomicIntegerFieldUpdater:原子更新整型字段的更新器
- AtomicLongFieldUpdater原子更新长整型字段的更新器
- AtomicStampedReference :原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于解决原子的更新数据和数据的版本号,可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。
- AtomicMarkableReference原子更新带有标记的引用类型。该类将 boolean 标记与引用关联起来,也可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。
- AtomicMarkableReference原子更新带有标记的引用类型。该类将 boolean 标记与引用关联起来,~~也可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。~~
> 修正: **AtomicMarkableReference 不能解决ABA问题**
```java
/**
AtomicMarkableReference是将一个boolean值作是否有更改的标记本质就是它的版本号只有两个true和false
修改的时候在这两个版本号之间来回切换这样做并不能解决ABA的问题只是会降低ABA问题发生的几率而已
@author : mazh
@Date : 2020/1/17 14:41
*/
public class SolveABAByAtomicMarkableReference {
private static AtomicMarkableReference atomicMarkableReference = new AtomicMarkableReference(100, false);
public static void main(String[] args) {
Thread refT1 = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
atomicMarkableReference.compareAndSet(100, 101, atomicMarkableReference.isMarked(), !atomicMarkableReference.isMarked());
atomicMarkableReference.compareAndSet(101, 100, atomicMarkableReference.isMarked(), !atomicMarkableReference.isMarked());
});
Thread refT2 = new Thread(() -> {
boolean marked = atomicMarkableReference.isMarked();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean c3 = atomicMarkableReference.compareAndSet(100, 101, marked, !marked);
System.out.println(c3); // 返回true,实际应该返回false
});
refT1.start();
refT2.start();
}
}
```
**CAS ABA 问题**
- 描述: 第一个线程取到了变量 x 的值 A然后巴拉巴拉干别的事总之就是只拿到了变量 x 的值 A。这段时间内第二个线程也取到了变量 x 的值 A然后把变量 x 的值改为 B然后巴拉巴拉干别的事最后又把变量 x 的值变为 A (相当于还原了)。在这之后第一个线程终于进行了变量 x 的操作,但是此时变量 x 的值还是 A所以 compareAndSet 操作是成功。