自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一不小心就翻車(chē)!volatile 和 Atomic 的區(qū)別,你真的清楚嗎?

開(kāi)發(fā) 前端
通俗點(diǎn)說(shuō),Java 的 volatile 變量類(lèi)似于“全員廣播”模式。每當(dāng)某個(gè)線程修改了這個(gè)變量,其他線程都能立刻看到最新的值,不會(huì)出現(xiàn)“臟數(shù)據(jù)”。

引言

小米最近在準(zhǔn)備社招面試,畢竟在互聯(lián)網(wǎng)這條“卷”路上,稍微停滯不前,就可能被更年輕的程序員們彎道超車(chē)。為了在面試中脫穎而出,小米最近瘋狂刷面試題,尤其是多線程相關(guān)的知識(shí)。

這天,小米和面試官約了一場(chǎng)線上面試,一上來(lái)面試官就丟出了一個(gè)高頻問(wèn)題:

“Java 中 volatile 變量和 Atomic 變量有什么不同?”

小米心里一緊,心想:“這不就是面試八股文里常見(jiàn)的問(wèn)題嗎?” 于是,他開(kāi)始了自信的作答……

volatile 變量:能見(jiàn)度好,但不保證原子性

1. volatile 是什么?

小米微微一笑,說(shuō)道:

volatile 關(guān)鍵字的作用是保證變量的可見(jiàn)性,防止指令重排序。

通俗點(diǎn)說(shuō),Java 的 volatile 變量類(lèi)似于“全員廣播”模式。每當(dāng)某個(gè)線程修改了這個(gè)變量,其他線程都能立刻看到最新的值,不會(huì)出現(xiàn)“臟數(shù)據(jù)”。

2. volatile 如何保證可見(jiàn)性?

JMM(Java 內(nèi)存模型) 規(guī)定,volatile 變量在寫(xiě)入時(shí),會(huì)多做一步操作:

  • 普通變量賦值: 線程先從主內(nèi)存中讀取數(shù)據(jù),復(fù)制到自己的工作內(nèi)存,修改后再寫(xiě)回主內(nèi)存,其他線程無(wú)法感知這個(gè)變化。
  • volatile 變量賦值: 直接刷新到主內(nèi)存,并讓所有線程的緩存失效,從而保證所有線程都能立即看到最新的值。

就像是小米早上給群發(fā)了一條消息:“今天團(tuán)建改到 3 點(diǎn)!” 這樣,所有人都能立即收到,而不會(huì)有人還在按照原來(lái)的時(shí)間去行動(dòng)。

3. 但 volatile 不能保證原子性

面試官點(diǎn)了點(diǎn)頭,然后笑著問(wèn):“那 volatile 變量能保證原子性嗎?”

小米立刻搖頭:“不能!”

他舉了個(gè)例子:

圖片圖片

看上去 count++ 只是一個(gè)簡(jiǎn)單的自增操作,但實(shí)際上它是三步操作:

  • 讀取 count 的值
  • 執(zhí)行 +1 操作
  • 將新值寫(xiě)回 count

如果有兩個(gè)線程 A 和 B 同時(shí)執(zhí)行 increment() 方法:

  • A 讀取 count=0,執(zhí)行 count+1,還沒(méi)來(lái)得及寫(xiě)回
  • B 也讀取 count=0,執(zhí)行 count+1,然后寫(xiě)回
  • A 最后寫(xiě)回 count=1

本來(lái)執(zhí)行兩次 increment(),結(jié)果 count 還是 1,丟失了一次更新!這就是“并發(fā)問(wèn)題”。

所以,volatile 僅僅保證了變量的可見(jiàn)性,并不能保證操作的原子性!

Atomic 變量:天生線程安全,保證原子性

小米接著說(shuō)道:“如果想保證原子性,Java 提供了 java.util.concurrent.atomic 包,里面的 Atomic 變量是更好的選擇?!?/p>

1. 什么是 Atomic 變量?

Atomic 變量 依靠 CAS(Compare-And-Swap) 機(jī)制來(lái)保證原子性。

還是剛才的例子,如果我們改用 AtomicInteger:

圖片圖片

這樣,多個(gè)線程同時(shí)調(diào)用 increment() 方法時(shí),就不會(huì)丟失數(shù)據(jù)了。

2. Atomic 如何保證原子性?

Atomic 變量的核心是 CAS(比較并交換,Compare-And-Swap),它的原理是:

  • 讀取舊值 oldValue
  • 計(jì)算新值 newValue
  • 使用 CPU 指令 嘗試將 oldValue 更新為 newValue
  • 如果 oldValue 還是舊值,就更新成功;如果已經(jīng)被其他線程修改了,就重新嘗試。

這種方式避免了傳統(tǒng)的 鎖(synchronized) 帶來(lái)的性能問(wèn)題,CAS 是無(wú)鎖并發(fā)的基礎(chǔ),比 synchronized 更高效!

不過(guò),CAS 也不是萬(wàn)能的,它可能導(dǎo)致“ABA 問(wèn)題”(變量值在中間被修改了,但最終又變回去了),解決方案是 AtomicStampedReference 這種帶版本號(hào)的原子變量。

volatile vs Atomic:到底該選誰(shuí)?

面試官看小米講得這么清楚,問(wèn)道:“所以,在實(shí)際開(kāi)發(fā)中,volatile 和 Atomic 該怎么選呢?”

小米總結(jié)道:

圖片圖片

如果只是需要保證變量的可見(jiàn)性,而不涉及并發(fā)修改,可以使用 volatile,比如:

  • 線程間的標(biāo)志位
  • double check 機(jī)制的 instance 變量

如果需要保證變量的原子性,應(yīng)該使用 Atomic 變量,比如:

  • 計(jì)數(shù)器(AtomicInteger)
  • 線程安全的累加器(LongAdder)

面試官的加分題

面試官滿意地點(diǎn)了點(diǎn)頭,然后問(wèn):“那 synchronized 和 Atomic 有什么不同呢?”

小米心想:“這不就是送分題嗎?”

他笑著回答:

  • synchronized 是一種阻塞式的同步機(jī)制,線程會(huì)進(jìn)入阻塞狀態(tài),性能開(kāi)銷(xiāo)較大。
  • Atomic 變量是非阻塞的,它基于 CAS 操作,不會(huì)讓線程進(jìn)入阻塞狀態(tài),因此更高效。
  • synchronized 適合需要多個(gè)變量一起同步的場(chǎng)景,而 Atomic 適合單個(gè)變量的無(wú)鎖操作。

面試官點(diǎn)頭:“不錯(cuò),今天的面試到這里,回去等通知吧!”

小米掛斷電話,感覺(jué)這次面試發(fā)揮得不錯(cuò),心里暗自高興。為了幫助更多正在找工作的朋友,他在朋友圈里分享了今天的面試知識(shí)點(diǎn):

  • volatile 只保證可見(jiàn)性,不保證原子性
  • Atomic 變量使用 CAS 機(jī)制,保證原子性,適用于計(jì)數(shù)、累加等操作
  • synchronized 適用于多個(gè)變量的同步,Atomic 適用于單個(gè)變量的高效無(wú)鎖操作
責(zé)任編輯:武曉燕 來(lái)源: 軟件求生
相關(guān)推薦

2021-07-28 05:01:29

Lombok前端測(cè)試

2023-03-10 08:27:07

for循環(huán)項(xiàng)目線性結(jié)構(gòu)

2018-01-18 22:26:30

2021-01-05 22:49:37

Python編程語(yǔ)言Java

2020-10-26 08:56:32

技術(shù)總監(jiān)程序員

2021-04-30 08:21:22

Linux管道設(shè)計(jì)

2021-03-29 18:47:53

APP服務(wù)端通信安全數(shù)據(jù)安全

2021-10-07 16:45:06

MySQL數(shù)據(jù)庫(kù)

2024-05-13 07:58:52

開(kāi)源項(xiàng)目PR

2021-01-30 09:50:54

MySQL密碼服務(wù)器

2020-10-28 15:07:01

Arthas

2019-09-19 20:47:29

刷臉支付人臉識(shí)別人工智能

2020-09-29 07:44:20

跨域前后端分離插件

2020-04-30 09:45:41

安卓App小米

2022-09-27 18:19:32

Java數(shù)據(jù)結(jié)構(gòu)

2021-01-22 10:27:28

人工智能機(jī)器學(xué)習(xí)技術(shù)

2021-01-08 09:36:23

程序員比特幣黑客

2019-07-29 14:38:35

服務(wù)器開(kāi)發(fā)工具

2019-06-24 10:51:01

3D打印打印機(jī)

2016-10-17 08:58:23

Windows 7殺毒賬號(hào)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)