Java 原子性實現(xiàn) CAS操作 AtomInteger類

更多 Java 并發(fā)編程方面的文章,請參見文集《Java 并發(fā)編程》


原子操作

不會被線程調(diào)度機制打亂的操作,一旦開始候生,就一直運行到結(jié)束纱皆。

注意拇惋,i++, ++i, i--, --i 不是原子操作,以 i++ 為例抹剩,實際上它包括了以下三個步驟撑帖,在多線程情況下每一步都可能會被打亂:

  • 1,讀取 i
  • 2澳眷,操作 i + 1
  • 3胡嘿,寫回內(nèi)存

例如如下代碼:
開啟 100 個線程,同時執(zhí)行 i++钳踊,最后結(jié)果并不能保證是 100衷敌。

public class Atom_Test {
    private static int i = 0;

    public static void main(String[] args) {
        for (int j = 0; j < 100; j++) {
            new Thread() {
                public void run() {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                    }

                    i++;
                }
            }.start();
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }

        System.out.println(i);
    }
}

CAS操作

CAS操作是一種 CPU 原語,性能較好拓瞪。

CAS操作基于樂觀鎖缴罗,基本流程如下:

  • 1,在操作之前讀取內(nèi)存值祭埂,設為 期望數(shù)據(jù)
  • 2面氓,在 期望數(shù)據(jù) 上操作(如 +1)得到 新數(shù)據(jù)
  • 3,compareAndSet( 期望數(shù)據(jù), 新數(shù)據(jù)) 方法先比較當前內(nèi)存值是否與 期望數(shù)據(jù) 相等:
    • 如果相等蛆橡,寫入 新數(shù)據(jù)
    • 如果不等舌界,說明該數(shù)據(jù)在此期間已經(jīng)被其他線程修改,因此不寫入 新數(shù)據(jù)泰演,而是重新執(zhí)行步驟 1

CAS操作可能存在的問題:
ABA 問題呻拌,即內(nèi)存值實際上被其他線程修改過,例如從 A 修改為 B睦焕,隨后又修改為 A藐握,這樣當前線程會誤認為該數(shù)據(jù)在此期間沒有被其他線程修改。

atomic 包

java.util.concurrent.atomic 包提供了原子操作的類垃喊,例如

  • AtomicInteger
  • AtomicLong
  • AtomicBoolean
  • AtomicReference

AtomicInteger猾普,它提供了支持原子操作的方法,包括:

  • int get()
  • int getAndSet(int newValue)
  • int getAndIncrement()
  • int incrementAndGet()
  • int getAndDecrement()
  • int decrementAndGet()

例如如下代碼:
我們使用 AtomicInteger 替代了 int缔御,這樣可以確保最后的結(jié)果是 100抬闷。

public class Atom_Test {
    private static AtomicInteger i = new AtomicInteger(0);

    public static void main(String[] args) {
        for (int j = 0; j < 100; j++) {
            new Thread() {
                public void run() {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                    }

                    i.getAndIncrement();
                }
            }.start();
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }

        System.out.println(i);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子笤成,更是在濱河造成了極大的恐慌评架,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件炕泳,死亡現(xiàn)場離奇詭異纵诞,居然都是意外死亡,警方通過查閱死者的電腦和手機培遵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進店門浙芙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人籽腕,你說我怎么就攤上這事嗡呼。” “怎么了皇耗?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵南窗,是天一觀的道長。 經(jīng)常有香客問我郎楼,道長万伤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任呜袁,我火速辦了婚禮敌买,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘阶界。我一直安慰自己虹钮,他們只是感情好,可當我...
    茶點故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布荐操。 她就那樣靜靜地躺著芜抒,像睡著了一般珍策。 火紅的嫁衣襯著肌膚如雪托启。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天攘宙,我揣著相機與錄音屯耸,去河邊找鬼。 笑死蹭劈,一個胖子當著我的面吹牛疗绣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播铺韧,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼多矮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起塔逃,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤讯壶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后湾盗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伏蚊,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年格粪,在試婚紗的時候發(fā)現(xiàn)自己被綠了躏吊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡帐萎,死狀恐怖比伏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情疆导,我是刑警寧澤凳怨,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站是鬼,受9級特大地震影響肤舞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜均蜜,卻給世界環(huán)境...
    茶點故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一李剖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧囤耳,春花似錦篙顺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至椎麦,卻和暖如春封救,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背碱蒙。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工役衡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嘁捷。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓造成,卻偏偏與公主長得像,于是被迫代替她去往敵國和親雄嚣。 傳聞我的和親對象是個殘疾皇子晒屎,可洞房花燭夜當晚...
    茶點故事閱讀 45,926評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Java8張圖 11、字符串不變性 12、equals()方法鼓鲁、hashCode()方法的區(qū)別 13履肃、...
    Miley_MOJIE閱讀 3,710評論 0 11
  • 接著上節(jié) mutex,本節(jié)主要介紹atomic的內(nèi)容坐桩,練習代碼地址尺棋。本文參考http://www.cplusplu...
    jorion閱讀 73,697評論 1 14
  • 從三月份找實習到現(xiàn)在,面了一些公司绵跷,掛了不少膘螟,但最終還是拿到小米、百度碾局、阿里荆残、京東、新浪净当、CVTE内斯、樂視家的研發(fā)崗...
    時芥藍閱讀 42,281評論 11 349
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法像啼,內(nèi)部類的語法俘闯,繼承相關的語法,異常的語法忽冻,線程的語...
    子非魚_t_閱讀 31,668評論 18 399
  • 整理一下真朗,明天回校。
    假裝沒想到閱讀 166評論 0 1