新四季網

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學習小組」。全棧工程師學習計劃

關注我們,加入「全棧工程師學習計劃」。

版權聲明

原創不易,未經允許不得轉載!

,
同类文章
葬禮的夢想

葬禮的夢想

夢見葬禮,我得到了這個夢想,五個要素的五個要素,水火只好,主要名字在外面,職業生涯良好,一切都應該對待他人治療誠意,由於小,吉利的冬天夢想,秋天的夢是不吉利的
找到手機是什麼意思?

找到手機是什麼意思?

找到手機是什麼意思?五次選舉的五個要素是兩名士兵的跡象。與他溝通很好。這是非常財富,它擅長運作,職業是仙人的標誌。單身男人有這個夢想,主要生活可以有人幫忙
我不怎麼想?

我不怎麼想?

我做了什麼意味著看到米飯烹飪?我得到了這個夢想,五線的主要土壤,但是Tu Ke水是錢的跡象,職業生涯更加真誠。他真誠地誠實。這是豐富的,這是夏瑞的巨星
夢想你的意思是什麼?

夢想你的意思是什麼?

你是什​​麼意思夢想的夢想?夢想,主要木材的五個要素,水的跡象,主營業務,主營業務,案子應該抓住魅力,不能疏忽,春天夢想的吉利夢想夏天的夢想不幸。詢問學者夢想
拯救夢想

拯救夢想

拯救夢想什麼意思?你夢想著拯救人嗎?拯救人們的夢想有一個現實,也有夢想的主觀想像力,請參閱週宮官方網站拯救人民夢想的詳細解釋。夢想著敵人被拯救出來
2022愛方向和生日是在[質量個性]中

2022愛方向和生日是在[質量個性]中

[救生員]有人說,在出生88天之前,胎兒已經知道哪天的出生,如何有優質的個性,將走在什麼樣的愛情之旅,將與生活生活有什么生活。今天
夢想切割剪裁

夢想切割剪裁

夢想切割剪裁什麼意思?你夢想切你的手是好的嗎?夢想切割手工切割手有一個真正的影響和反應,也有夢想的主觀想像力。請參閱官方網站夢想的細節,以削減手
夢想著親人死了

夢想著親人死了

夢想著親人死了什麼意思?你夢想夢想你的親人死嗎?夢想有一個現實的影響和反應,還有夢想的主觀想像力,請參閱夢想世界夢想死亡的親屬的詳細解釋
夢想搶劫

夢想搶劫

夢想搶劫什麼意思?你夢想搶劫嗎?夢想著搶劫有一個現實的影響和反應,也有夢想的主觀想像力,請參閱週恭吉夢官方網站的詳細解釋。夢想搶劫
夢想缺乏缺乏紊亂

夢想缺乏缺乏紊亂

夢想缺乏缺乏紊亂什麼意思?你夢想缺乏異常藥物嗎?夢想缺乏現實世界的影響和現實,還有夢想的主觀想像,請看官方網站的夢想組織缺乏異常藥物。我覺得有些東西缺失了