首先碑诉,我們要理解什么叫原子操作常遂,原子操作可以理解為:在多線程操作同一對(duì)象時(shí)纳令,在非程序代碼加鎖狀況下,保證被操作對(duì)象是結(jié)果是符合預(yù)期的克胳。
翻譯為人話就是:一個(gè)數(shù)泊碑,很多線程去同時(shí)修改它,不加sync同步鎖毯欣,就可以保證修改結(jié)果是正確的馒过。
那它是如何保證的呢?我們先了解一個(gè)叫CAS的東西:
CAS(Compare and swap):比較和替換是設(shè)計(jì)并發(fā)算法時(shí)用到的一種技術(shù)酗钞。簡(jiǎn)單來(lái)說(shuō)腹忽,比較和替換是使用一個(gè)期望值和一個(gè)變量的當(dāng)前值進(jìn)行比較来累,如果當(dāng)前變量的值與我們期望的值相等,就使用一個(gè)新值替換當(dāng)前變量的值窘奏。CAS是一種系統(tǒng)原語(yǔ)(所謂原語(yǔ)屬于操作系統(tǒng)用語(yǔ)范疇嘹锁。原語(yǔ)由若干條指令組成的,用于完成一定功能的一個(gè)過程着裹。primitive or atomic action 是由若干個(gè)機(jī)器指令構(gòu)成的完成某種特定功能的一段程序领猾,具有不可分割性·即原語(yǔ)的執(zhí)行必須是連續(xù)的,在執(zhí)行過程中不允許被中斷)骇扇。CAS是Compare And Set的縮寫摔竿。CAS有3個(gè)操作數(shù),內(nèi)存值V少孝,舊的預(yù)期值A(chǔ)继低,要修改的新值B。當(dāng)且僅當(dāng)預(yù)期值A(chǔ)和內(nèi)存值V相同時(shí)稍走,將內(nèi)存值V修改為B袁翁,否則什么都不做。
可以說(shuō)婿脸,原子操作正是靠CAS算法保證的粱胜。可能有人會(huì)有疑問:CAS是比較替換算法狐树,會(huì)不會(huì)同時(shí)有兩個(gè)線程同時(shí)比較且同時(shí)替換年柠?答案當(dāng)然是:不會(huì)。
為什么不會(huì)褪迟?我們來(lái)看一下紅色字體的內(nèi)容,前方高能答憔,需要操作系統(tǒng)的知識(shí):
1味赃、原語(yǔ)由若干條指令組成的,用于完成一定功能的一個(gè)過程虐拓。
2心俗、即原語(yǔ)的執(zhí)行必須是連續(xù)的,在執(zhí)行過程中不允許被中斷蓉驹。
在x86 平臺(tái)上城榛,CPU提供了在指令執(zhí)行期間對(duì)總線加鎖的手段。CPU芯片上有一條引線#HLOCK pin态兴,如果匯編語(yǔ)言的程序中在一條指令前面加上前綴'LOCK'狠持,經(jīng)過匯編以后的機(jī)器代碼就使CPU在執(zhí)行這條指令的時(shí)候把#HLOCK pin的電位拉低,持續(xù)到這條指令結(jié)束時(shí)放開瞻润,從而把總線鎖住喘垂,這樣同一總線上別的CPU就暫時(shí)不能通過總線訪問內(nèi)存了甜刻,保證了這條指令在多處理器環(huán)境中的原子性。
所以正勒,不會(huì)存在兩個(gè)線程同時(shí)比較得院、同時(shí)替換。另外章贞,因?yàn)镃AS是基于樂觀鎖的祥绞,也就是說(shuō)當(dāng)寫入的時(shí)候,如果寄存器舊值已經(jīng)不等于現(xiàn)值鸭限,說(shuō)明有其他CPU在修改蜕径,那就繼續(xù)嘗試。所以這就保證了操作的原子性里覆。因此在大請(qǐng)求量的性能表現(xiàn)上丧荐,CAS樂觀鎖也是可以大大提高吞吐量的。
Atomic正是采用了CAS算法喧枷,所以可以在多線程環(huán)境下安全地操作對(duì)象虹统。
總之,原子操作的基石是:CPU對(duì)總線加鎖隧甚,加鎖的方式叫:拉低電位(一串0101010100101呼嘯而過)车荔。
然而,volatile是Java的關(guān)鍵字戚扳,官方解釋:volatile可以保證可見性忧便、順序性、一致性帽借。
下面解讀一下:
可見性:volatile修飾的對(duì)象在加載時(shí)會(huì)告知JVM珠增,對(duì)象在CPU的緩存上對(duì)多個(gè)線程是同時(shí)可見的。
順序性:這里有JVM的內(nèi)存屏障的概念砍艾,簡(jiǎn)單理解為:可以保證線程操作對(duì)象時(shí)是順序執(zhí)行的蒂教,詳細(xì)了解可以自行查閱。
一致性:可以保證多個(gè)線程讀取數(shù)據(jù)時(shí)脆荷,讀取到的數(shù)據(jù)是最新的凝垛。(注意讀取的是最新的數(shù)據(jù),但不保證寫回時(shí)不會(huì)覆蓋其他線程修改的結(jié)果)
基于上面的信息蜓谋,大概可以初步了解volatile多線程下非原子性了梦皮。