java編程基礎教程idea激活碼(Java原子操作第八章)
2023-09-21 10:09:44 1
難度初級
學習時間30分鐘
適合人群零基礎
開發語言Java
開發環境JDK v11IntelliJIDEA v2018.3友情提示本教學屬於系列教學,內容具有連貫性,本章使用到的內容之前教學中都有詳細講解。本章內容針對零基礎或基礎較差的同學比較友好,可能對於有基礎的同學來說很簡單,希望大家可以根據自己的實際情況選擇繼續看完或等待看下一篇文章。謝謝大家的諒解!1.溫故知新前面在《「全棧2019」Java原子操作第三章:比較並交換CAS技術詳解》一章中介紹了什麼是比較並交換CAS技術。
在《「全棧2019」Java原子操作第四章:AtomicBoolean介紹與使用》一章中介紹了什麼是原子操作類AtomicBoolean。
在《「全棧2019」Java原子操作第五章:AtomicInteger介紹與使用》一章中介紹了什麼是原子操作類AtomicInteger。
在《「全棧2019」Java原子操作第六章:AtomicInteger靈活的運算方式》一章中介紹了使用原子操作類AtomicInteger的方法實現更靈活的運算方式。
在《「全棧2019」Java原子操作第七章:AtomicLong介紹與使用》一章中介紹了什麼是原子操作類AtomicLong。
現在介紹原子操作類AtomicReference。
2.什麼是原子操作類?顧名思義,原子操作類就是實現了原子操作的類。
原子操作的概念和必備知識在該系列的《「全棧2019」Java原子操作第一章:內存可見性volatile關鍵字解析》和《「全棧2019」Java原子操作第二章:i 是原子操作嗎?何為原子性》以及《「全棧2019」Java原子操作第三章:比較並交換CAS技術詳解》三章中已經詳細介紹過了,這裡就不再贅述。不清楚的小夥伴請前去查閱相關章節。
2.AtomicReference簡介對於學過該系列的第一、二、三章的小夥伴來說,原子操作類就顯得簡單很多,而且裡面的原理已經掌握得差不多了,所以本章就簡單來介紹一下原子操作類之一:AtomicReference。
AtomicReference類很簡單,它有兩個構造方法:
如下:
AtomicReferenceAtomicReference(V initialValue)這兩個構造方法都比較常用。
第二個構造方法AtomicReference(V initialValue)可以指定初始值。
下面我們就來用一用AtomicReference。
3.AtomicReference應用場景AtomicReference應用也比較廣泛,只要是對象操作是原子的,都可以使用到AtomicReference。
例如,我們之前說到的計數器,那時用的是AtomicInteger,沒有用Integer,那是因為Integer不帶原子操作。現在可以用Integer了,因為只需將Integer與AtomicReference結合即可,這樣我們以原子的方式更新Integer對象,也就不存在並發問題了。
如果大家有更多關於AtomicReference的應用場景請在評論區留言,謝謝。
下面,來看看未使用AtomicReference的時候會是怎樣。
例子是全局計數器。
首先,我們創建一個全局計數器類:
然後,將其構造方法進行私有化,目的是不讓創建對象,只能使用其靜態方法:
接著,定義一個Integer類型的變量記錄當前生成的計數器:
然後,定義一個方法來獲取當前計數器的值:
接著,再定義一個方法來遞增計數器的值:
全局計數器類寫好了。
接下來,我們去試試全局計數器。
在Main類中創建一個計數任務:
接著,在run方法裡面調用全局計數器對象的遞增方法:
run方法書寫完畢。
然後,我們創建100個線程去執行計數任務:
最後,等這100個線程都執行完計數任務任務以後,我們再次獲取計數器的當前值:
如果當前計數器的值是100,則說明每個線程都有自己唯一的計數,都是不同的;
如果當前計數器的值不是100,則說明有計數相同的線程,全局計數器這個類就有問題。
不過在此之前需要睡1秒鐘,目的是等這100個線程執行完畢之後我們再獲取當前計數器的值:
例子書寫完畢。
運行程序,執行結果:
從運行結果來看,不符合預期。當前計數不為100,說明全局計數器這個類是有問題的。
怎麼解決?
這時我們的AtomicReference類派上用場了。
我們只需用AtomicReference替換Integer類型即可:
因為AtomicReference替換Integer,所以獲取當前計數器的值的方法和遞增當前計數器的值的方法都得改變。
先是獲取當前計數器的值的方法:
然後是遞增當前計數器的值的方法:
對於學過前面幾章的小夥伴來說,get方法和getAndUpdate(UnaryOperator updateFunction)方法不陌生,get方法是用來獲取value的當前值;getAndUpdate(UnaryOperator updateFunction)方法是用來更新value對象當前值的,我們可以自定義更新方式。
註:getAndUpdate(UnaryOperator updateFunction)方法在下面小節會有詳細講解。
例子改寫完畢。
運行程序,執行結果:
從運行結果來看,符合預期。當前計數為100,全局計數器這個類的問題得到了解決。
當然了,除了給Java已經存在的對象賦予原子性,我們還可以給自定義對象賦予原子性。
下面,我們就來一個自定義對象Person:
然後,在Person類中定義兩個屬性,姓名和年齡:
接著,我們給Person類增加一個有參構造方法,而且還要保留無參構造方法:
最後,給Person類中的name和age屬性提供getter/setter方法:
自定義對象寫好了。
下面就用AtomicReference與Person類來說說AtomicReference類裡面幾個常用方法及源碼。
對於學過《「全棧2019」Java原子操作第五章:AtomicInteger介紹與使用》和《「全棧2019」Java原子操作第七章:AtomicLong介紹與使用》兩章的小夥伴來說,掌握下面的內容輕而易舉,因為變化的僅僅是將int、long類型變為對象類型。
註:因為下面內容在之前章節中講過太多次,所以此次內容會得到精簡,以便閱讀。
4.獲取當前值get方法get方法的作用是獲取對象的當前值;
例子:
運行程序,執行結果:
從運行結果來看,符合預期。
5.設置新值set(V newValue)方法set(V newValue)方法的作用是設置對象的當前值。參數newValue是我們可以指定的新值。
例子:
運行程序,執行結果:
從運行結果來看,符合預期。
6.返回更新前的值getAndUpdate(UnaryOperator updateFunction)方法getAndUpdate(UnaryOperator updateFunction)方法的作用是返回更新前的值。
例子:
運行程序,執行結果:
從運行結果來看,符合預期。即使在getAndUpdate(UnaryOperator updateFunction)方法中設置了新值,但方法則返回的是更新前的值。
7.返回更新後的值updateAndGet(UnaryOperator updateFunction)方法updateAndGet(UnaryOperator updateFunction)方法的作用是返回更新後的值。
例子:
運行程序,執行結果:
從運行結果來看,符合預期。我們在updateAndGet(UnaryOperator updateFunction)方法中設置了新值,方法即時返回了新值。
8.返回自定義運算方式更新前的值getAndAccumulate(V x, BinaryOperator accumulatorFunction)方法getAndAccumulate(V x, BinaryOperator accumulatorFunction)方法的作用是返回自定義運算方式更新前的值。
例子:
運行程序,執行結果:
從運行結果來看,符合預期。原值為「Tom:18」,然後我們在getAndAccumulate(V x, BinaryOperator accumulatorFunction)方法中設置了新值「Jack:23」,方法返回了更新前的值「Tom:18」。
9.返回自定義運算方式更新後的值accumulateAndGet(V x, BinaryOperator accumulatorFunction)方法accumulateAndGet(V x, BinaryOperator accumulatorFunction)方法的作用是返回自定義運算方式更新前的值。
例子:
運行程序,執行結果:
從運行結果來看,符合預期。原值為「Tom:18」,然後我們在accumulateAndGet(V x, BinaryOperator accumulatorFunction)方法中設置了新值「Jack:23」,方法返回了更新後的值「Jack:23」。
10.CAS算法體現我們之前在《「全棧2019」Java原子操作第三章:比較並交換CAS技術詳解》一章中學習過什麼是CAS算法。
在AtomicReference類中也有體現:
compareAndSet(V expectedValue, V newValue)方法的作用是當value==expectedValue時,就將newValue賦給value,否則什麼也不做。
例子:
運行程序,執行結果:
從運行結果來看,符合預期。
當然了,你也可以將預期值改為一個非原值的數,這樣賦值就不成功。
最後,希望大家可以把這個例子照著寫一遍,然後再自己默寫一遍,方便以後碰到類似的面試題可以輕鬆應對。
祝大家編碼愉快!
GitHub本章程序GitHub地址:https://github.com/gorhaf/Java2019/tree/master/Thread/atomic/AtomicReference
總結AtomicReference是一個以原子方式操作對象的類。get方法的作用是獲取對象的當前值;set(V newValue)方法的作用是設置對象的當前值。參數newValue是我們可以指定的新值。getAndUpdate(UnaryOperator updateFunction)方法的作用是返回更新前的值。updateAndGet(UnaryOperator updateFunction)方法的作用是返回更新後的值。getAndAccumulate(V x, BinaryOperator accumulatorFunction)方法的作用是返回自定義運算方式更新前的值。accumulateAndGet(V x, BinaryOperator accumulatorFunction)方法的作用是返回自定義運算方式更新前的值。compareAndSet(V expectedValue, V newValue)方法的作用是當value==expectedValue時,就將newValue賦給value,否則什麼也不做。至此,Java中AtomicReference相關內容講解先告一段落,更多內容請持續關注。
答疑如果大家有問題或想了解更多前沿技術,請在下方留言或評論,我會為大家解答。
上一章「全棧2019」Java原子操作第七章:AtomicLong介紹與使用
下一章「全棧2019」Java原子操作第九章:atomic包下原子數組介紹與使用
學習小組加入同步學習小組,共同交流與進步。
方式一:關注頭條號Gorhaf,私信「Java學習小組」。方式二:關注公眾號Gorhaf,回復「Java學習小組」。全棧工程師學習計劃關注我們,加入「全棧工程師學習計劃」。
原創不易,未經允許不得轉載!
,