<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # CAS CAS是compare and swap的縮寫,是一種多線程無鎖的編程方式。當修改多個線程可能同時操作的屬性時,給定`期望值`和`要更新的值`,如果`當前值`與`期望值`一致,則更新為要設置的值。CAS的底層是通過將讀取-比較-設置三個操作作為一個指令執行,在執行期間不會有其他線程改變變量。這保證了操作的原子性。 CAS其以樂觀的態度進行操作,不斷循環等待進行,對比而言,線程切換需要8萬個cup時鐘周期,而循環重試只需要幾個cup時鐘。 ## 性能對比 下面以synchronized與cas進行對比,重點在于 ``` // 1. 使用synchronized static int count = 0; final Object lock = new Object(); Thread ths [] = new Thread[10000]; for(int i=0;i<ths.length;i++) { Thread thread = new Thread(new Runnable() { public void run() { for(int i=0;i<10000;i++) { synchronized (lock) { count ++; } } } }); ths[i] = thread; } long begin = System.currentTimeMillis(); for(int i=0;i<ths.length;i++) { ths[i].start(); ths[i].join(); } System.out.println(count);// 100000000 System.out.println(System.currentTimeMillis() - begin); //5269 ``` 使用CAS的測試 ``` final AtomicInteger count = new AtomicInteger(0); Thread ths [] = new Thread[10000]; for(int i=0;i<ths.length;i++) { Thread thread = new Thread(new Runnable() { public void run() { for(int i=0;i<10000;i++) { count.incrementAndGet(); } } }); ths[i] = thread; } long begin = System.currentTimeMillis(); for(int i=0;i<ths.length;i++) { ths[i].start(); ths[i].join(); } System.out.println(count.get());// 100000000 System.out.println(System.currentTimeMillis() - begin); // 1863 ``` 從上面可以看到,CAS比線程切換的方式快2.8倍以上。 ## 主要類 * AtomicBoolean * AtomicInteger * AtomicIntegerArray * AtomicIntegerFieldUpdater * AtomicLong * AtomicLongArray * AtomicLongFieldUpdater * AtomicMarkableReference 原子更新帶有標記位的引用類型 * AtomicReference 原子更新引用類型 * AtomicReferenceArray 原子更新引用數組 * AtomicReferenceFieldUpdater 原子更新引用類型里的字段 * AtomicStampedReference **主要方法:** * set(newVal)/get() 賦值、獲取當前值 * lazySet(newVal) * getAndSet(newVal) 原子性設置值 * compareAndSet(exp,upd) 比較并設置值 * getAndIncrement() * incrementAndGet() ## ABA問題 假如鏈表為: head->A->B->C,線程t1要將head->B,cas(A,B),此過程中線程t2進行了head->A->C->D,此時B已經處于游離狀態,B.next=null,切換到線程t1,t1發現header還是A,就進行交換 head->B,這時鏈表丟失了C和D。 以上就是由于ABA問題帶來的隱患,各種樂觀鎖的實現中通常都會用版本戳version來對記錄或對象標記,避免并發操作帶來的問題,在Java中,AtomicStampedReference<E>也實現了這個功能。 ``` private static AtomicStampedReference atomicStampedRef = new AtomicStampedReference(100, 0); //初始值為100,初始時間戳為0 atomicStampedRef.compareAndSet(100, 101, atomicStampedRef.getStamp(), atomicStampedRef.getStamp() + 1); //cas 還要判斷時間戳 atomicStampedRef.compareAndSet(101, 100, atomicStampedRef.getStamp(), atomicStampedRef.getStamp() + 1); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看