1. 程式人生 > >原始碼學習【原子類AtomicInteger】Java原子類底層實現(解釋詳細)

原始碼學習【原子類AtomicInteger】Java原子類底層實現(解釋詳細)

原子類AtomicInteger

在Java中,有很多方法可以保證多執行緒下資料的安全,AtomicXXXX這些類就是其中的一種,原子類,可以保證每一步操作都是原子操作。這次就對AtomicInteger的原始碼進行學習。

首先看一下這個類的類變數和成員變數:

//類變數 unsafe類【java不能直接訪問作業系統底層,而是通過本地方法來訪問。Unsafe類提供了硬體級別的原子操作】
//這裡的這個變數就是用來進行cpu級別的原子操作。
private static final Unsafe unsafe = Unsafe.getUnsafe();
//這個變數實際上是由下面的static塊來賦值的,可以由賦值看出來,這個值是下面的value屬性在每個AtomikInteger物件中的位置偏移量,用這個值既可以找到在具體每個物件的記憶體中的記憶體地址。
private static final long valueOffset;

static {
    try {
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
    } catch (Exception ex) { throw new Error(ex); }
}
//volatile修飾,AtomicInteger的值,在直接記憶體中,多個執行緒下可以直接獲取值。
private volatile int value;

看完了這個類的內部的變數,其實大概可以猜到這個類怎麼完成的原子操作了,使用volatile修飾的value來儲存值,保證每個執行緒都可以隨時讀到值,然後每一步操作都使用CAS(compare and swap)這樣即可以保證一直能原子寫入,下面來看看原始碼到底是不是這樣。

來看一下incrementAndGet這個方法,實際上就是++i的操作,但是保證原子性。

 public final int incrementAndGet() {
    //用get出來的值+1,前面的方法是unsafe中實現的 i++。對value屬性進行操作。
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

//Unsafe中的。這個方法可以看到一直在做do-while,直到CAS成功(獲取AtomicInteger物件上的value屬性,然後CAS檢查保證值是var5的時候將他變成var5+1)。
//其中getIntVolatile和compareAndSwapInt 都是native方法,用C寫的。CAS底層貌似是使用了cpu的cpxchg(compare*change)。
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;
}

總結

所有其他的方法都大同小異,使用volatile修飾的value來儲存值,保證每個執行緒都可以隨時讀到值,然後每一步操作都使用CAS(compare and swap)這樣即可以保證原子寫入。

相關推薦

原始碼學習原子AtomicIntegerJava原子底層實現解釋詳細

原子類AtomicInteger 在Java中,有很多方法可以保證多執行緒下資料的安全,AtomicXXXX這些類就是其中的一種,原子類,可以保證每一步操作都是原子操作。這次就對AtomicInteger的原始碼進行學習。 首先看一下這個類的類變數和成員變數

夾娃系列java面試基礎知識儲備¥1——java的優點和C++的異同點

怎麼才能夾到布娃娃 沒錯!!這個文章就是告訴你怎麼才能用一個硬幣,抓到最多的布娃娃QAQ,這是我抓娃娃的第一個硬幣¥1.【宣告】夾娃系列純屬個人學習,參考了不少面試的書,《程式設計之美》、《演算法珠璣》、《劍指offer》、《java程式設計師

夾娃系列java面試基礎知識儲備¥2——JVM記憶體劃分和記憶體溢位異常的原因和解決方法

JVM記憶體劃分和記憶體溢位 JVM記憶體劃分 記憶體溢位的異常和解決辦法 JVM記憶體劃分 堆:存放物件例項,被所有的執行緒共享的一塊區域。垃圾收集器管理的主要區域。 方法區:儲存虛擬機器載入的類資訊,常量,靜態變

原始碼學習HashMap第一篇HashMap到底是怎麼put的?

HashMap到底是怎麼put 的? 這是我的專欄的第一篇,有任何錯誤,希望大家不吝賜教,共同學習。 寫這個專欄主要是自己學習原始碼的過程,如果對別人能有所幫助,不勝開心~ Put的流程: resize流程圖: 關於HashMap中的紅黑樹這裡不做討論,後續

Java面試11常問問題及答案非常詳細

Java面試常問問題及答案(非常詳細) 一:java基礎 1.簡述string物件,StringBuffer、StringBuilder區分 string是final的,內部用一個final型別的char陣列儲存資料,它的拼接效率比較低,實際上是通過建立一個StringBuffer,讓後臺呼叫a

小程式java 後臺獲取使用者資訊解密encryptedData

首先java 後端依賴兩個jar <dependency> <groupId>org.codehaus.xfire</groupId> <artifactId>xfire-core</artifac

神經網路與深度學習Win10+VS2015 caffe環境搭建極其詳細

caffe是好用,可是配置其環境實在是太痛苦了,依賴的庫很多不說,在VS上編譯還各種報錯,你能想象那種被一百多個紅色提示所籠罩的恐懼。  且網上很多教程是VS2013環境下編譯的,問人很多也說讓我把15解除安裝了裝13,我的答案是:偏不  記下這個艱難的過程,萬一還要再來

達內課程音樂播放器4.0播放準備

這一節我們需要實現播放歌曲的功能。想要實現播放歌曲,需要得到歌曲的url地址。由於上一節的介面中我們得到的歌曲列表中並沒有歌曲地址,所以我們需要根據song_id再次傳送請求,獲取歌曲url 百度音樂api介面 流程如下 NewMusicListFragment 中給listv

CF套題Codeforces Round #524 (Div. 2) 1080A~F

原題地址 迴歸 CF \text {CF} CF,這場堪堪上紫。 A.Petya and Origa

暗戀神器QQ空間爬蟲-Python版pyzone-crawler

宣告 在你心中是否有一個默默關注的小姐姐? 你是否想知道在遇見她之前在她身邊的一切? 確認過眼神,讓你總在對的時間遇上對的人 寫這個外掛純粹是出於學習目的,此博文主要作用是功能

資料結構鏈式棧的實現C語言

棧的鏈式儲存稱為鏈式棧,鏈式棧是一種特殊的單鏈表,它的插入和刪除規定在單鏈表的同一端進行。鏈式棧的棧頂指標一般用top表示。(個人理解:相當於只對單鏈表的第一個結點進行操作) 鏈式棧要掌握以下基本操作: 1、建立一個空鏈式棧 2、判斷鏈式棧是否為空 3、讀鏈式棧的

Spring Bean的生命週期非常詳細

Spring作為當前Java最流行、最強大的輕量級框架,受到了程式設計師的熱烈歡迎。準確的瞭解Spring Bean的生命週期是非常必要的。我們通常使用ApplicationContext作為Spring容器。這裡,我們講的也是 ApplicationContext中Be

2018.12.08FJOI2014BZOJ4016洛谷P2993最短路徑樹問題最短路點分治

BZOJ傳送門 洛谷傳送門 解析: 辛辛苦苦調了半天發現是最短路樹建錯了。。。 思路: 首先跑一個最短路,然後將每個點的所有出邊按照出點編號排序,DFS建出最短路樹。 這樣建樹才能夠保證字典序是最小的。(naive的我按照前驅結點建樹WA哭了) 那麼看一

洛谷2468[SDOI2010] 粟粟的書架二合一

點此看題面 大致題意: 問你選取一個矩形區間內至少幾個數,才能使它們的和≥Hi\ge H_i≥Hi​。 二合一 根據資料範圍,比較顯然能看出它是一道二合一的題目。 對於第一種情況,R,C≤200R,C\le 200R,C≤200,我們可以用字首和+二分去做。

2018.12.24python3.7+OpenCV 人臉識別圖片+攝像頭

一、識別影象中的人臉個數。註釋寫的很好(\(^o^)/恩) #!/practice/Study_Test python # -*- coding: utf-8 -*- # @Time : 2018/12/23 21:19 # @Author : yb.w # @File : ima

視覺-立體視覺全域性匹配演算法SGBM實現含動態規劃DP詳解

最近一直在學習SGBM演算法,作為一種全域性匹配演算法,立體匹配的效果明顯好於區域性匹配演算法,但是同時複雜度上也要遠遠大於區域性匹配演算法。演算法主要是參考Stereo Processing by Semiglobal Matching and Mutual Informa

資料結構演算法約瑟夫環問題線性表

據說著名猶太曆史學家 Josephus有過以下的故事:在羅馬人佔領喬塔帕特後,39 個猶太人與Josephus及他的朋友躲到一個洞中,39個猶太人決定寧願死也不要被敵人抓到,於是決定了一個自殺方式,41個人排成一個圓圈,由第1個人開始報數,每報數到第3人該人就必須自殺,然後再由下一個重新報數,直到所有人都自殺

Eclipse開發工具 修改 Web 專案的名稱圖文案例

開啟Eclipse 切換到  Navigator 檢視,能顯現出專案下所有的檔案便於修改 1、修改該專案目錄下:.project檔案 <projectDescription> <n

Java同步處理底層實現monitor 可重入鎖)

對於Java同步處理可以參考這篇部落格:https://blog.csdn.net/sophia__yu/article/details/83990755 但是這些處理方法的底層實現是怎樣呢? 接下里將會解釋同步程式碼塊、同步方法、全域性鎖的底層實現。 同步程式碼塊底層實現: 首

簡單選擇排序演算法原理及java實現詳細

選擇排序是一種非常簡單的排序演算法,就是在序列中依次選擇最大(或者最小)的數,並將其放到待排序的數列的起始位置。 簡單選擇排序的原理 簡單選擇排序的原理非常簡單,即在待排序的數列中尋找最大(或者最小)的一個數,與第 1 個元素進行交換,接著在剩餘的待排序的數列中繼續找最大(最小)的一個數,與第 2 個元素交