JUC中Atomic包分析
併發場景中,為了保證執行緒安全,也就是臨界區程式碼按照我們所想的時序執行,需要進行加鎖,也就是同步控制,但是有很多情況,不需要我們自己進行同步控制,而是可以使用java自帶的併發元件,本文主要講Atomic包中提供原子操作的類,接下來我們依次分析。
AtomicInteger
相信應該是用的最多的原子操作類了,它的主要作用是進行int型別變數的包裝,讓變數的操作都是執行緒安全。如何實現呢?最容易想到的應該是每個方法進行加鎖控制,這是沒問題的。但juc中並非這種方式,而是使用了volatile進行可見性控制和失敗重試的CAS操作來保證成功的原子性,這也是樂觀鎖一種實現。
關於CAS操作:每次修改資料時,都會比較資料的原值,如果原值沒有改變,代表沒有其他執行緒進行併發修改,可以安全更新,如果原值改變了,代表有執行緒成功修改了此值,則此次更新失敗。
AtomicInteger提供了很多有用的方法,當然我不會一一分析,就說說常用的,在原始碼基礎是進行註釋。
/**因為value變數是用volatile修飾的所以get永遠是獲取的最新值*/
public final int get() {
return value;
}
//原理同get()
public final void set(int newValue) {
value = newValue;
}
/**獲取原值並且設定新增,這個方法應該用的比較少,因為這個原值可能已經不是我們希望的了,但是這步操作會成功的改變原值*/
public final int getAndSet(int newValue) {
for (;;) {
int current = get();
if (compareAndSet(current, newValue))
return current;
}
}
/**這就是cas的實現,對先查詢後更新操作進行原子性保障,原理是直接通過記憶體偏移量進行記憶體最新資料的比較,如果記憶體中的資料是所希望的,表示沒有其他的執行緒進行修改,那麼就可以進行正確的更新*/
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
/**此方法應該是最常用的,這是執行緒安全的i++操作,並返回原值*/
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
//如果i++後需要返回新值,則是下面的
public final int incrementAndGet() ;
// 同理i--操作也是提供兩個
public final int getAndDecrement();//返回原值
public final int decrementAndGet();//返回新增
/**那麼有i++,那麼如果i+n呢,同樣也有兩個*/
public final int getAndSet(int newValue);//返回舊值
public final int addAndGet(int delta);//返回新值
總的來說AtomicInteger,就是執行緒安全的int型別,同時提供了很多上面的常見操作,合理的使用,可以在併發程式設計中減輕很多的工作。
AtomicBoolean
實現的原理和AtomicInteger一樣,底層還是用int型別,並不是boolean,就不復制原始碼了,簡單的說下常用的方法:
方法 | 描述 |
---|---|
boolean get() | 獲取最新值 |
set(boolean newValue) | 設定成newValue |
boolean compareAndSet(boolean expect, boolean update) | cas設值 |
boolean getAndSet(boolean newValue) | 設定newValue並返回原值 |
如果僅僅是為了賦值操作,那麼也沒有必要AtomicBoolean,因為jvm虛擬機器規範中規定,除了long和double型別外其他的任何型別賦值操作都是原子的,只需進行volatile修飾,保證可見性就能對單一的賦值操作進行同步保證。
AtomicLong
AtomicLong的實現可以說和AtomicInteger的一模一樣,同樣那些操作,不過包裝的是long型罷了,這裡就不細細分析了。
AtomicReference
AtomicReference和AtomicBoolean的使用可以說一模一樣,只不過包裝的是物件的引用,需要注意的是,物件的比較操作不是通過==或者equals,而是比較的引用的的指標位置。
其他
其他的陣列的實現,原理都一樣,cas操作,AtomicIntegerArray和AtomicInteger不同的地方在於,操作的方法需要帶上陣列元素的位置,也就是索引,AtomicLongArray,AtomicReferenceArray同樣可以類比AtomicLong和AtomicReference,這裡就不詳細說明了。
總之,在新的併發場景中,還是儘量使用執行緒安全的現有元件,安全可靠且規範。
相關推薦
JUC中Atomic包分析
併發場景中,為了保證執行緒安全,也就是臨界區程式碼按照我們所想的時序執行,需要進行加鎖,也就是同步控制,但是有很多情況,不需要我們自己進行同步控制,而是可以使用java自帶的併發元件,本文主要講Atomic包中提供原子操作的類,接下來我們依次分析。 Atomi
Java中Atomic包的原理和分析
原文地址:http://blog.csdn.net/zhangerqing/article/details/43057799 Atomic簡介 Atomic包是Java.util.concurrent下的另一個專門為執行緒安全設計的Java包,包含多個原子操作類。這個
JUC之atomic包
相關概念之原子性: 原子性是指一個操作或多個操作要麼全部執行,且執行的過程不會被任何因素打斷,要麼都不執行。 atomic包是java.util.concurrent下的一個專門為執行緒安全設計的java包,該包下包含多個原子操作類: atomic包下
JUC中Atomic class之lazySet的一點疑惑
最近再次翻netty和disrupt的原始碼, 發現一些地方使用AtomicXXX.lazySet()/unsafe.putOrderedXXX系列, 以前一直沒有注意lazySet這個方法, 仔細研究一下發現很有意思。我們拿AtomicReferenceFieldUpdater的set()和
24.Java中atomic包中的原子操作類總結
tun 添加 原來 說明 array 內存地址 void rri delta 1. 原子操作類介紹 在並發編程中很容易出現並發安全的問題,有一個很簡單的例子就是多線程更新變量i=1,比如多個線程執行i++操作,就有可能獲取不到正確的值,而這個問題,最常用的方法是通過Sy
併發程式設計面試必備:JUC 中的 Atomic 原子類總結
個人覺得這一節掌握基本的使用即可! 本節思維導圖: 1 Atomic 原子類介紹 Atomic 翻譯成中文是原子的意思。在化學上,我們知道原子是構成一般物質的最小單位,在化學反應中是不可分割的。在我們這裡 Atomic 是指一個操作是不可中斷的。即使是在多個執行緒一起執行的時
Golang中heap包原始碼分析
heap的實現使用到了小根堆,下面先對堆做個簡單說明 1. 堆概念 堆是一種經過排序的完全二叉樹,其中任一非終端節點的資料值均不大於(或不小於)其左孩子和右孩子節點的值。 最大堆和最小堆是二叉堆的兩種形式。 最大堆:根結點的鍵值是所有堆結點鍵值中最大者。 最小
Java多執行緒學習(九)JUC 中的 Atomic 原子類總結
阿里雲產品 1888 代金券領取:https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=hf47liqn 本節思維導圖: 1 Atomic 原子類介紹 Atomic 翻譯成中文是原
Java併發程式設計包中atomic的實現原理
這是一篇來自粉絲的投稿,作者【林灣村龍貓】最近在閱讀Java原始碼,這一篇是他關於併發包中atomic類的原始碼閱讀的總結。Hollis做了一點點修改。 引子 在多執行緒的場景中,我們需要保證資料安全,就會考慮同步的方案,通常會使用synchronized或者lo
WebRTC中丟包重傳NACK實現分析
在WebRTC中,前向糾錯(FEC)和丟包重傳(NACK)是抵抗網路錯誤的重要手段。FEC在傳送端將資料包新增冗餘糾錯碼,糾錯碼連同資料包一起傳送到接收端;接收端根據糾錯碼對資料進行檢查和糾正。RFC5109[1]定義FEC資料包的格式。NACK則在接收端檢測到資料丟包後,傳
Linux核心分析_UDP協議中資料包的收發處理過程
1.前言 實驗基於Linux kernel 3.18.6,實驗內容包括: (1)編寫UDP客戶端和服務端 (2)將UDP客戶端和服務端整合到MenuOS中 (3)UDP傳送資料的過程 (4)UDP接收資料的過程 本文中完整原始碼:https://github.com
Java中的Atomic包使用指南
本文首發於併發網,作者:方騰飛 引言 Java從JDK1.5開始提供了java.util.concurrent.atomic包,方便程式設計師在多執行緒環境下,無鎖的進行原子操作。原子變數的底層使用了處理器提供的原子指令,但是不同的CPU架構可能提供的原子指令不一樣,也有可能需要某種形式的內部
Java中的Atomic包使用指南:AtomicInteger、AtomicBoolean、AtomicIntegerArray、AtomicReference……
本文首發於併發網,作者:方騰飛 引言 Java從JDK1.5開始提供了java.util.concurrent.atomic包,方便程式設計師在多執行緒環境下,無鎖的進行原子操作。原子變數的底層使用了處理器提供的原子指令,但是不同的CPU架構可能提供的原子指令
Live555中RTP包的打包與傳送過程分析
afterGettingFrame1函式的複雜之處在於處理frame的分片,若一個frame大於TCP/UDP有效載荷(程式中定義為1448個位元組),就必需分片了。最簡單的情況就是一個packet(RTP包)中最多隻充許一個frame,即一個RTP包中存在一個frame或者frame的一個分片,H264就是
atomic包的原理及分析
currently turn 適合 call jdk 相對 sent 可能 location Atomic簡介 Atomic包是java.util.concurrent下的另一個專門為線程安全設計的Java包,包含多個原子操作類。這個包裏面提供了一組原子變量類。其基本的特性
資料包分析中Drop和iDrop的區別
資料包分析中Drop和iDrop的區別 在資料包分析中,Drop表示因為過濾丟棄的包。為了區分發送和接受環節的過
JUC 中的 Atomic 原子類總結
1 Atomic 原子類介紹 Atomic 翻譯成中文是原子的意思。在化學上,我們知道原子是構成一般物質的最小單位,在化學反應中是不可分割的。在我們這裡 Atomic 是指一個操作是不可中斷的。即使是在多個執行緒一起執行的時候,一個操作一旦開始,就不會被其他執行緒干擾。 所以,所謂原子類說簡單點
【極客思考】計算機網路:Wireshark抓包分析TCP中的三次握手與四次揮手
【摘要】本文重點分析計算機網路中TCP協議中的握手和揮手的過程。 【前提說明】 前段時間突然看到了一篇關於TCP/IP模型的文章,心想這段時間在家裡也用wireshark抓了點包,那麼想著想著就覺得需要複習一下網路知識,於是就有這篇博文的誕生。當然網上關於TCP相關的知識點也是芸芸,閒著無事也可以多googl
GO中常用包筆記 bytes(四)
g 學習筆記 bytes包Package bytes對字節數組進行操作的包。功能和strings包相似.bytes包提供的功能有:和另一個字節數組切片的關系(逐字節比較大小,是否相等/相似,是否包含/包含次數,位置搜索,是否是前綴後綴)2.字節數組切片和字符串的關系(字符串中是否含有字節數組所包含的rune,
PHP中phar包的使用
ets php 修改 使用 file sets new 擴展 set PHP5.3之後支持了類似Java的jar包,名為phar。用來將多個PHP文件打包為一個文件。 首先需要修改php.ini配置將phar的readonly關閉,默認是不能寫phar包的,include是