原始碼學習【原子類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)這樣即可以保證原子寫入。
相關推薦
原始碼學習【原子類AtomicInteger】Java原子類底層實現(解釋詳細)
原子類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.08【FJOI2014】【BZOJ4016】【洛谷P2993】最短路徑樹問題(最短路)(點分治)
BZOJ傳送門 洛谷傳送門 解析: 辛辛苦苦調了半天發現是最短路樹建錯了。。。 思路: 首先跑一個最短路,然後將每個點的所有出邊按照出點編號排序,DFS建出最短路樹。 這樣建樹才能夠保證字典序是最小的。(naive的我按照前驅結點建樹WA哭了) 那麼看一
【洛谷2468】[SDOI2010] 粟粟的書架(二合一)
點此看題面 大致題意: 問你選取一個矩形區間內至少幾個數,才能使它們的和≥Hi\ge H_i≥Hi。 二合一 根據資料範圍,比較顯然能看出它是一道二合一的題目。 對於第一種情況,R,C≤200R,C\le 200R,C≤200,我們可以用字首和+二分去做。
【2018.12.24】python3.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 個元素交