溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

java并發(fā)編程之cas的示例分析

發(fā)布時(shí)間:2021-08-11 10:46:16 來(lái)源:億速云 閱讀:168 作者:小新 欄目:編程語(yǔ)言

這篇文章給大家分享的是有關(guān)java并發(fā)編程之cas的示例分析的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

CAS(Compare and swap)比較和替換是設(shè)計(jì)并發(fā)算法時(shí)用到的一種技術(shù)。簡(jiǎn)單來(lái)說(shuō),比較和替換是使用一個(gè)期望值和一個(gè)變量的當(dāng)前值進(jìn)行比較,如果當(dāng)前變量的值與我們期望的值相等,就使用一個(gè)新值替換當(dāng)前變量的值。

CAS的使用場(chǎng)景

在程序和算法中一個(gè)經(jīng)常出現(xiàn)的模式就是“check and act”模式。先檢查后操作模式發(fā)生在代碼中首先檢查一個(gè)變量的值,然后再基于這個(gè)值做一些操作。下面是一個(gè)簡(jiǎn)單的示例:

class MyLock {
  private boolean locked = false;
  public boolean lock() {
    if(!locked) {
      locked = true;
      return true;
    }
    return false;
  }
}

上面這段代碼,如果用在多線程的程序會(huì)出現(xiàn)很多錯(cuò)誤,不過(guò)現(xiàn)在請(qǐng)忘掉它。

如你所見(jiàn),lock()方法首先檢查locked>成員變量是否等于false,如果等于,就將locked設(shè)為true。

如果同個(gè)線程訪問(wèn)同一個(gè)MyLock實(shí)例,上面的lock()將不能保證正常工作。如果一個(gè)線程檢查locked的值,然后將其設(shè)置為false,與此同時(shí),一個(gè)線程B也在檢查locked的值,又或者,在線程A將locked的值設(shè)為false之前。因此,線程A和線程B可能都看到locked的值為false,然后兩者都基于這個(gè)信息做一些操作。

為了在一個(gè)多線程程序中良好的工作,”checkthenact”操作必須是原子的。原子就是說(shuō)”check“操作和”act“被當(dāng)做一個(gè)原子代碼塊執(zhí)行。不存在多個(gè)線程同時(shí)執(zhí)行原子塊。

下面是一個(gè)代碼示例,把之前的lock()方法用synchronized關(guān)鍵字重構(gòu)成一個(gè)原子塊。

class MyLock {
  private boolean locked = false;
  public synchronized boolean lock() {
    if(!locked) {
      locked = true;
      return true;
    }
    return false;
  }
}

現(xiàn)在lock()方法是同步的,所以,在某一時(shí)刻只能有一個(gè)線程在同一個(gè)MyLock實(shí)例上執(zhí)行它。

原子的lock方法實(shí)際上是一個(gè)”compare and swap“的例子。

CAS用作原子操作

現(xiàn)在CPU內(nèi)部已經(jīng)執(zhí)行原子的CAS操作。Java5以來(lái),你可以使用java.util.concurrent.atomic包中的一些原子類來(lái)使用CPU中的這些功能。

下面是一個(gè)使用AtomicBoolean類實(shí)現(xiàn)lock()方法的例子:

public static class MyLock {
  private AtomicBoolean locked = new AtomicBoolean(false);
  public boolean lock() {
    return locked.compareAndSet(false, true);
  }
}

locked變量不再是boolean類型而是AtomicBoolean。這個(gè)類中有一個(gè)compareAndSet()方法,它使用一個(gè)期望值和AtomicBoolean實(shí)例的值比較,和兩者相等,則使用一個(gè)新值替換原來(lái)的值。在這個(gè)例子中,它比較locked的值和false,如果locked的值為false,則把修改為true。

如果值被替換了,compareAndSet()返回true,否則,返回false。

使用Java5+提供的CAS特性而不是使用自己實(shí)現(xiàn)的的好處是Java5+中內(nèi)置的CAS特性可以讓你利用底層的你的程序所運(yùn)行機(jī)器的CPU的CAS特性。這會(huì)使還有CAS的代碼運(yùn)行更快。

感謝各位的閱讀!關(guān)于“java并發(fā)編程之cas的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI