欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java并發(fā)編程之原子操作類詳情

 更新時(shí)間:2022年04月15日 17:58:24   作者:派大大大星?  
這篇文章主要介紹了Java并發(fā)編程之原子操作類詳情,文章基于Java并發(fā)編程展開相關(guān)內(nèi)容,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

JUC包提供了一系列的原子性操作類,這些類都是使用非阻塞算法CAS實(shí)現(xiàn)的,相比使用鎖實(shí)現(xiàn)原子性操作者在性能上有很大提升。JUC包中含有AtomicInteger、AtomicLong、AtomicBoolean,它們的原理類似。下面我們以AtomicLong為例來講解。

我們先來看一下部分源碼:

public class AtomicLong extends Number implements java.io.Serializable {
    private static final long serialVersionUID = 1927816293512124184L;

    //1.獲取Unsafe類實(shí)例
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    //2.存放value的偏移量
    private static final long valueOffset;
    static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();

    //3.用于判斷是否支持Long類型無鎖CAS
    private static native boolean VMSupportsCS8();

    static {
        try {
            //4.獲取value在AtomicLong中的偏移量
            valueOffset = unsafe.objectFieldOffset
                (AtomicLong.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }
    //5.實(shí)際變量值
    private volatile long value;

    /**
     * Creates a new AtomicLong with the given initial value.
     *
     * @param initialValue the initial value
     */
    public AtomicLong(long initialValue) {
        value = initialValue;
    }
    ············省略部分代碼·············
}

上面代碼中,代碼1處通過Unsafe.getUnsafe()獲取到Unsafe類的實(shí)例(因?yàn)锳tomicLong類是在rt.jar包下面的,AtomicLong類就是通過Bootstarp類加載器進(jìn)行加載的)。代碼5處,value被聲明為volatile類型,保證內(nèi)存的可見性。通過代碼2,4獲取value變量在AtomicLong類中的偏移量。

接下來介紹一下AtomicLong中的主要函數(shù):

  • 遞增和遞減代碼
//調(diào)用unsafe方法,設(shè)置value=value+1后,返回原始的值
public final long getAndIncrement() {
    return unsafe.getAndAddLong(this, valueOffset, 1L);
}

//調(diào)用unsafe方法,設(shè)置value=value-1后,返回原始的值
public final long getAndDecrement() {
    return unsafe.getAndAddLong(this, valueOffset, -1L);
}


//調(diào)用unsafe方法,設(shè)置value=value+1后,返回遞增后的值
public final long incrementAndGet() {
    return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;
}

//調(diào)用unsafe方法,設(shè)置value=value-1后,返回遞減后的值
public final long decrementAndGet() {
    return unsafe.getAndAddLong(this, valueOffset, -1L) - 1L;
}

上面的四個(gè)函數(shù)內(nèi)部都是通過調(diào)用Unsafe的getAndAddLong方法來實(shí)現(xiàn)操作,這個(gè)函數(shù)是個(gè)原子性操作,這里第一個(gè)參數(shù)是AtomicLong實(shí)例的引用的,第二個(gè)參數(shù)是value變量在AtomicLong的偏移值,第三個(gè)參數(shù)是要設(shè)置的第二個(gè)變量的值。

其中g(shù)etAndIncrement()方法在JDK7中實(shí)現(xiàn)邏輯為:

public final long getAndIncrement() {
    while(true) {
        long current = get();
        long next = current + 1;
        if (compareAndSet(current, next))
            return current;
    }
}

如上代碼中,每個(gè)線程是先拿到變量的當(dāng)前值(由于value是volatile變量,所以這是獲取的最新值),然后在工作內(nèi)存中對(duì)其進(jìn)行增1操作,而后使用CAS修改變量的值,如果設(shè)置失敗,則循環(huán)繼續(xù)嘗試,直到設(shè)置成功。

JDK8中的邏輯為:

public final long getAndIncrement() {
        retrturn unsafe.getAndAddLong(this, valueOffset, 1L);
    }

其中JDK8中的unsafe.getAndAddLong的代碼為:

public final long getAndAddLong(Object var1, long var2, long var4) {
   long var6;
   do {
       var6 = this.getLongVolatile(var1, var2);
   } while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4));

   return var6;
}

從中可以看到,JDK7中的AtomicLong中循環(huán)邏輯已經(jīng)被JDK8中的原子操作類Unsafe內(nèi)置了。

  • boolean compareAndSet(long expect,long update)
public final boolean compareAndSet(long expect,long update) 
{
    return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}

函數(shù)在內(nèi)部調(diào)用了unsafe.compareAndSwapLong方法。如果原子變量中的value值等于expect,則使用update值更新該值并返回true,否則返回false。

到此這篇關(guān)于Java并發(fā)編程之原子操作類詳情的文章就介紹到這了,更多相關(guān)Java 原子操作類內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java中Locks的使用詳解

    java中Locks的使用詳解

    這篇文章主要介紹了java中Locks的使用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • springboot?事件監(jiān)聽器的案例詳解

    springboot?事件監(jiān)聽器的案例詳解

    這篇文章主要介紹了springboot?事件監(jiān)聽器,springboot(spring)的事件監(jiān)聽器使用主要有兩種方式,通過實(shí)現(xiàn)ApplicationListener接口,另一個(gè)就是在類上添加 @EventListener 注解來實(shí)現(xiàn),接下來將對(duì)這兩種方式逐一說明,需要的朋友可以參考下
    2022-06-06
  • mybatis查詢oracle long類型的踩坑記錄

    mybatis查詢oracle long類型的踩坑記錄

    這篇文章主要介紹了mybatis查詢oracle long類型的踩坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Spring原生Rpc六種的正確打開方式實(shí)現(xiàn)示例

    Spring原生Rpc六種的正確打開方式實(shí)現(xiàn)示例

    這篇文章主要為大家展示了Spring原生Rpc六種的正確打開方式實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助祝大家多多進(jìn)步早日升職加薪
    2022-02-02
  • springboot2.x解決運(yùn)行順序及Bean對(duì)象注入順序的問題

    springboot2.x解決運(yùn)行順序及Bean對(duì)象注入順序的問題

    這篇文章主要介紹了springboot2.x解決運(yùn)行順序及Bean對(duì)象注入順序的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Java中報(bào)錯(cuò)org.springframework.jdbc.UncategorizedSQLException的多種解決方法

    Java中報(bào)錯(cuò)org.springframework.jdbc.UncategorizedSQLException的多種

    本文主要介紹了Java中報(bào)錯(cuò)org.springframework.jdbc.UncategorizedSQLException的多種解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 解析本地方法映射Java層的數(shù)據(jù)類型

    解析本地方法映射Java層的數(shù)據(jù)類型

    這篇文章給大家介紹了本地方法映射Java層的數(shù)據(jù)類型,包括基礎(chǔ)類型映射,引用類型映射等等,對(duì)java層數(shù)據(jù)類型映射相關(guān)知識(shí),感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-03-03
  • 詳解JVM系列之對(duì)象的鎖狀態(tài)和同步

    詳解JVM系列之對(duì)象的鎖狀態(tài)和同步

    鎖和同步是java多線程編程中非常常見的使用場景。為了鎖定多線程共享的對(duì)象,Java需要提供一定的機(jī)制來實(shí)現(xiàn)共享對(duì)象的鎖定。當(dāng)?shù)诙€(gè)線程進(jìn)入同一個(gè)區(qū)域的時(shí)候,必須等待第一個(gè)線程解鎖該對(duì)象。JVM是怎么做到的呢?快來一起看看吧。
    2021-06-06
  • spring AOP的Around增強(qiáng)實(shí)現(xiàn)方法分析

    spring AOP的Around增強(qiáng)實(shí)現(xiàn)方法分析

    這篇文章主要介紹了spring AOP的Around增強(qiáng)實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了spring面向切面AOP的Around增強(qiáng)具體步驟與相關(guān)操作方法,需要的朋友可以參考下
    2020-01-01
  • 關(guān)于@RequestParam注解的使用(簡單易懂)

    關(guān)于@RequestParam注解的使用(簡單易懂)

    這篇文章主要介紹了關(guān)于@RequestParam注解的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評(píng)論