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

Java CAS機(jī)制的一些理解

 更新時(shí)間:2021年05月12日 09:55:40   作者:詠_志  
這篇文章主要介紹了Java CAS機(jī)制的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下

多線程實(shí)踐

public class test {
    private static int x;
    public static void main(String[] args) throws InterruptedException {
        Thread task1 = new Thread(){
            @Override
            public void run() {
                super.run();
                for (int i=0; i<1000; i++){
                    x=x+1;
                }
            }
        };
        Thread task2 = new Thread(){
            @Override
            public void run() {
                super.run();
                for (int i=0; i<1000; i++){
                    x=x+1;
                }
            }
        };

        task1.start();
        task2.start();
        task1.join();
        task2.join();
        System.out.println(x);
    }
/*
1006
*///:~

兩個(gè)線程同時(shí)開啟,累加x,理想的情況下,輸出應(yīng)該是2000,但是最終是1006,因?yàn)槭嵌嗑€程的情況下,一次累加可能是兩個(gè)線程同時(shí)完成的。

public class test {
    private static AtomicInteger atomicInteger = new AtomicInteger();
    public static void main(String[] args) throws InterruptedException {
        Thread task1 = new Thread(){
            @Override
            public void run() {
                super.run();
                for (int i=0; i<1000; i++){
                    atomicInteger.incrementAndGet();
                }
            }
        };

        Thread task2 = new Thread(){
            @Override
            public void run() {
                super.run();
                for (int i=0; i<1000; i++){
                    atomicInteger.incrementAndGet();
                }
            }
        };

        task1.start();
        task2.start();
        task1.join();
        task2.join();
        System.out.println(atomicInteger.get());
    }
}/*
2000
*///:~

修改被累加對(duì)象x為AtomicInteger,最終結(jié)果是理想的2000。在此操作中并沒有使用鎖,原因是 AtomicInteger引入了CAS機(jī)制。

什么是CAS機(jī)制

CAS機(jī)制簡(jiǎn)單的說就是,比較交換,有預(yù)期值、舊值和內(nèi)存位置;取出舊值,交換新值。

為何AtomicInteger線程安全

源碼:

private static final long valueOffset;
...
public final int incrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
...
Unsafe
public final int getAndAddInt(Object var1, long var2, int var4) {
    int var5;
    do {
        var5 = this.getIntVolatile(var1, var2);
    } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

    return var5;
}

unsafe提供了硬件級(jí)別的原子操作 valueOffset是變量?jī)?nèi)存地址 從源碼可以看出,incrementAndGet是調(diào)用了unsafe.getAndAddInt,它是一種基于CAS機(jī)制實(shí)現(xiàn)的,var5是從主內(nèi)存中獲取最新當(dāng)前值,而這個(gè)值是所有線程都可見和共享的,與var4相加交換,如果失敗就一直自旋,直到更新值成功。

圖解CAS機(jī)制

可以看出來,CAS沒有使用了任何鎖,就完成了線程安全。 CAS的優(yōu)點(diǎn)很多,但是缺點(diǎn)也很多,比如ABA問題

ABA問題

什么是ABA問題

其實(shí)很好理解,A->B->A,A值雖然沒有變,但是已經(jīng)經(jīng)過了某種操作。

圖解

有什么影響

上面的線程1、2、3都完成它們自己的任務(wù),并沒有問題。但是如果它們是在轉(zhuǎn)賬,問題就打了,賬戶就無端端的不見了10塊錢。

解決

引入版本號(hào),可以解決問題,每次有相同的值時(shí),做一次版本累加,只要是版本號(hào)對(duì)不上就是被修改過

總結(jié)

優(yōu)點(diǎn): 在并發(fā)量不是很高的情況,避免了鎖帶來的消耗

缺點(diǎn):

  • 并發(fā)量高的情況下,如果多次修改不成功,一直循環(huán)修改,就會(huì)帶來cpu的持續(xù)消耗
  • 只能對(duì)變量進(jìn)行原子級(jí)別的安全修改,不能對(duì)代碼塊進(jìn)行安全操作。

以上就是Java CAS機(jī)制的一些理解的詳細(xì)內(nèi)容,更多關(guān)于Java CAS機(jī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java算法題解Leetcode15三數(shù)之和實(shí)例

    java算法題解Leetcode15三數(shù)之和實(shí)例

    這篇文章主要為大家介紹了java算法題解Leetcode15三數(shù)之和實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • JAVA中compareTo方法的使用小結(jié)

    JAVA中compareTo方法的使用小結(jié)

    compareTo方法的目的是用來比較兩個(gè)對(duì)象的大小的,本文主要介紹了JAVA中compareTo方法的使用小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • java發(fā)送kafka事務(wù)消息的實(shí)現(xiàn)方法

    java發(fā)送kafka事務(wù)消息的實(shí)現(xiàn)方法

    本文主要介紹了java發(fā)送kafka事務(wù)消息的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Java實(shí)現(xiàn)聯(lián)系人管理系統(tǒng)

    Java實(shí)現(xiàn)聯(lián)系人管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)聯(lián)系人管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 簡(jiǎn)單談?wù)凾hreadPoolExecutor線程池之submit方法

    簡(jiǎn)單談?wù)凾hreadPoolExecutor線程池之submit方法

    下面小編就為大家?guī)硪黄?jiǎn)單談?wù)凾hreadPoolExecutor線程池之submit方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • Java使用J4L識(shí)別驗(yàn)證碼的操作方法

    Java使用J4L識(shí)別驗(yàn)證碼的操作方法

    這篇文章主要介紹了Java使用J4L識(shí)別驗(yàn)證碼的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • java中利用List的subList方法實(shí)現(xiàn)對(duì)List分頁(yè)(簡(jiǎn)單易學(xué))

    java中利用List的subList方法實(shí)現(xiàn)對(duì)List分頁(yè)(簡(jiǎn)單易學(xué))

    本篇文章主要介紹了java中l(wèi)ist數(shù)據(jù)拆分為sublist實(shí)現(xiàn)頁(yè)面分頁(yè)的簡(jiǎn)單代碼,具有一定的參考價(jià)值,有需要的可以了解一下。
    2016-11-11
  • Java中不用第三個(gè)變量來互換兩個(gè)變量的值

    Java中不用第三個(gè)變量來互換兩個(gè)變量的值

    在程序運(yùn)行期間,隨時(shí)可能產(chǎn)生一些臨時(shí)數(shù)據(jù),應(yīng)用程序會(huì)將這些數(shù)據(jù)保存在一些內(nèi)存單元中,每個(gè)內(nèi)存單元都用一個(gè)標(biāo)識(shí)符來標(biāo)識(shí)。這些內(nèi)存單元被稱為變量,定義的標(biāo)識(shí)符就是變量名,內(nèi)存單元中存儲(chǔ)的數(shù)據(jù)就是變量的值
    2021-10-10
  • spring?和?idea?建議不要使用?@Autowired注解的原因解析

    spring?和?idea?建議不要使用?@Autowired注解的原因解析

    @Autowired?是Spring框架的注解,而@Resource是JavaEE的注解,這篇文章主要介紹了spring和idea建議不要使用@Autowired注解的相關(guān)知識(shí),需要的朋友可以參考下
    2023-11-11
  • java利用數(shù)組隨機(jī)抽取幸運(yùn)觀眾

    java利用數(shù)組隨機(jī)抽取幸運(yùn)觀眾

    這篇文章主要為大家詳細(xì)介紹了java利用數(shù)組隨機(jī)抽取幸運(yùn)觀眾,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05

最新評(píng)論