java中的case1怎么说_Java 中的 CAS 简述及原理解析
一、CAS 是什么?
CAS(Compare And Swap),比較并交換,它是一條CPU并發原語。它的功能是判斷內存某個位置的值是否為預期值,如果是則更新為新的值,這個過程是原子的。1 public class CASDemo {
2 public static void main(String[] args) {
3 AtomicInteger atomicInteger = new AtomicInteger(5);
4
5 System.out.print(atomicInteger.compareAndSet(5, 2019));
6 System.out.println(" the value are " + atomicInteger.get());
7
8 System.out.print(atomicInteger.compareAndSet(5, 1024));
9 System.out.println(" the value are " + atomicInteger.get());
10 }
11 }
CAS 并發原語體現在 Java 語言中就是 sun.misc.Unsafe 類中的各個方法。調用 Unsafe 類中的 CAS 方法,JVM 會幫我們實現 CAS 匯編指令。這是一種完全依賴于硬件的功能,通過它實現了原子操作,再次強調,由于CAS 是一種系統原語,原語屬于操作系統用語范疇,是由若干條指令組成,用于完成某個功能的一個過程,并且原語的執行必須是連續的,在執行過程中不允許中斷,也就是說 CAS 是一條原子指令,不會造成所謂的數據不一致的問題。
二、Unsafe 類
以 AtomicInteger 原子類為例:1 public class AtomicInteger extends Number implements java.io.Serializable {
2 private static final long serialVersionUID = 6214790243416807050L;
3
4 // setup to use Unsafe.compareAndSwapInt for updates
5 private static final Unsafe unsafe = Unsafe.getUnsafe();
6 private static final long valueOffset;
7
8 static {
9 try {
10 valueOffset = unsafe.objectFieldOffset
11 (AtomicInteger.class.getDeclaredField("value"));
12 } catch (Exception ex) { throw new Error(ex); }
13 }
14
15 private volatile int value;
16
17 // ...
18 }
2.1 參數解析UnSafe是CAS的核心類。由于Java 方法無法直接訪問底層,需要通過本地(native)方法來訪問,UnSafe相當于一個后門,基于該類可以直接操作特定內存的數據。Unsafe 類在于 sun.misc 包中,其內部方法操作可以像 C 的指針一樣直接操作內存,因為 Java 中 CAS 操作的執行依賴于 Unsafe 類的方法。
注意:Unsafe 類中所有的方法都是 native 修飾的,也就是說 Unsafe 類中的方法都是直接調用操作底層資源執行相應任務。
變量 valueOffset,便是該變量在內存中的偏移地址,因為 Unsafe 就是根據內存偏移地址獲取數據的。
變量 value 用 volatile 修飾,保證了多線程之間的可見性。
2.2 方法示例解析
以 AtomicInteger 原子類中的 getAndIncrement() 為例:1 /**
2 * AtomicInteger.java 類中的相當于自增的方法
3 */
4 public final int getAndIncrement() {
5 return unsafe.getAndAddInt(this, valueOffset, 1);
6 }
7
8 // Unsafe 類中獲取指定內存區域變量的值
9 public native int getIntVolatile(Object var1, long var2);
10
11
12 /**
13 * Unsafe 類中的方法
14 * @param var1 當前 AtomicInteger 對象
15 * @param var2 變量在內存中的偏移地址
16 * @param var4 變量的增量
17 * 方法解析:
18 * 首先調用 getIntVolatile() 方法獲取指定內存區域的變量的值存儲到 var5 中,
19 * 要進行增值操作前,再重新從該地址獲取值與 var5 比較,
20 * 如果相同,則更新 var5 的值,并返回true,取反后,退出循環,返回相加后的值;
21 * 如果不相同,返回 false,循環繼續,重新取值,直到更新成功
22 */
23 public final int getAndAddInt(Object var1, long var2, int var4) {
24 int var5;
25 do {
26 var5 = this.getIntVolatile(var1, var2);
27 } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
28
29 return var5;
30 }
三、CAS 的缺點
3.1 循環時間長導致開銷變大
如果 CAS 一直獲取不到值,那么就會給 CPU 帶來很大的開銷。
3.2 只能保證一個共享變量的原子性
對多個共享變量操作時,循環CAS就無法保證操作的原子性,這個時候就可以用鎖來保證原子性。
3.3 ABA 問題
CAS算法實現一個重要前提是需要取出內存中某時刻的數據并在當下時刻比較并替換,那么在這個時間差內會導致數據的變化。
比如說一個線程 one 從內存位置 V 中取出 A,這時候另一個線程 two 也從內存中取出 A,并且線程 two 進行了一些操作將值變成了 B,然后線程 two 又將 V 位置的數據變成 A,這時候線程 one 進行CAS操作發現內存中仍然是 A,然后線程 one 操作成功。
盡管線程 one 的 CAS 操作成功,但是不代表這個過程就是沒有問題的。
ABA 問題的解決可通過 java.util.concurrent.atomic.AtomicStampedReference; 帶時間戳的原子引用類來解決。
標簽:var5,Java,CAS,Unsafe,AtomicInteger,簡述,內存,類中
來源: https://www.cnblogs.com/lveyHang/p/11883224.html
總結
以上是生活随笔為你收集整理的java中的case1怎么说_Java 中的 CAS 简述及原理解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java登录失败重新登录_为什么我的一直
- 下一篇: java美元兑换,(Java实现) 美元