摘要:多線程主要就是圍繞可見(jiàn)性和原子性這兩個(gè)特性展開(kāi)的,關(guān)鍵字對(duì)應(yīng)著可見(jiàn)性,但很多時(shí)候人們誤以為使用了關(guān)鍵字后編寫(xiě)多線程就沒(méi)問(wèn)題了,不知道它不能保證原子性。
說(shuō)起volatile和sychronized這兩個(gè)關(guān)鍵字,學(xué)習(xí)過(guò)多線程的同學(xué)應(yīng)該都很熟悉,在jdk1.5之前,主要就是靠這兩個(gè)關(guān)鍵字來(lái)做多線程編程的,但在jdk1.5以后,多了一個(gè)java.util.concurrent(JUC)包,里面包含了很多工具類用于多線程編程。但今天的重點(diǎn)還是講講volatile關(guān)鍵字。
多線程主要就是圍繞可見(jiàn)性和原子性這兩個(gè)特性展開(kāi)的,volatile關(guān)鍵字對(duì)應(yīng)著可見(jiàn)性,但很多時(shí)候人們誤以為使用了volatile關(guān)鍵字后編寫(xiě)多線程就沒(méi)問(wèn)題了,不知道它不能保證原子性。
首先來(lái)說(shuō)說(shuō)什么是可見(jiàn)性?要說(shuō)到可見(jiàn)性,就得扯到j(luò)ava內(nèi)存模型了,暫且不做太多展開(kāi),簡(jiǎn)單理解下就是,現(xiàn)在技術(shù)的提升,使得cpu的核心數(shù)不斷增多,而每個(gè)核心又擁有自己的緩存,當(dāng)處理數(shù)據(jù)時(shí)會(huì)有以下幾個(gè)步驟:
將數(shù)據(jù)從內(nèi)存讀取到緩存中
在緩存中對(duì)數(shù)據(jù)進(jìn)行操作
將緩存中的數(shù)據(jù)寫(xiě)入內(nèi)存中
步驟2中的操作并不是原子性,也就是在步驟1之后,如果主內(nèi)存變量發(fā)生修改之后,線程工作內(nèi)存中的值由于已經(jīng)加載,不會(huì)產(chǎn)生對(duì)應(yīng)的變化,所以計(jì)算出來(lái)的結(jié)果會(huì)和預(yù)期不一樣
對(duì)于volatile修飾的變量,jvm虛擬機(jī)只是保證從主內(nèi)存加載到線程工作內(nèi)存的值是最新的
正是因?yàn)檫@幾個(gè)步驟的存在,往往別的核心從內(nèi)存中讀取到的數(shù)據(jù)不是最新的,這就造成了數(shù)據(jù)錯(cuò)誤。java為了屏蔽操作系統(tǒng)以及硬件之間的不同,在jvm中虛擬出了一套內(nèi)存模型,編碼時(shí)使用volatile關(guān)鍵字對(duì)需要實(shí)時(shí)可見(jiàn)的數(shù)據(jù)修飾,在jvm底層會(huì)對(duì)該變量做特定的處理。
總結(jié)下可見(jiàn)性就是當(dāng)多個(gè)線程操作共享數(shù)據(jù)時(shí),保證操作的數(shù)據(jù)是最新的。
volatile關(guān)鍵字的作用?剛也說(shuō)過(guò)volatile關(guān)鍵字對(duì)應(yīng)的可見(jiàn)性,但這是其中之一,它有兩個(gè)作用:
1)使用volatile關(guān)鍵字修飾的變量,保證了其在多線程之間的可見(jiàn)性,即每次讀取到volatile變量,一定是最新的數(shù)據(jù)
2)代碼底層執(zhí)行不像我們看到的高級(jí)語(yǔ)言—-Java程序這么簡(jiǎn)單,它的執(zhí)行是Java代碼–>字節(jié)碼–>根據(jù)字節(jié)碼執(zhí)行對(duì)應(yīng)的C/C++代碼–>C/C++代碼被編譯成匯編語(yǔ)言–>和硬件電路交互,現(xiàn)實(shí)中,為了獲取更好的性能JVM可能會(huì)對(duì)指令進(jìn)行重排序,多線程下可能會(huì)出現(xiàn)一些意想不到的問(wèn)題。使用volatile則會(huì)對(duì)禁止語(yǔ)義重排序,當(dāng)然這也一定程度上降低了代碼執(zhí)行效率
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/67732.html
摘要:三關(guān)鍵字能保證原子性嗎并發(fā)編程藝術(shù)這本書(shū)上說(shuō)保證但是在自增操作非原子操作上不保證,多線程編程核心藝術(shù)這本書(shū)說(shuō)不保證。多線程訪問(wèn)關(guān)鍵字不會(huì)發(fā)生阻塞,而關(guān)鍵字可能會(huì)發(fā)生阻塞關(guān)鍵字能保證數(shù)據(jù)的可見(jiàn)性,但不能保證數(shù)據(jù)的原子性。 系列文章傳送門(mén): Java多線程學(xué)習(xí)(一)Java多線程入門(mén) Java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(1) java多線程學(xué)習(xí)(二)synchroniz...
摘要:當(dāng)一個(gè)線程持有重量級(jí)鎖時(shí),另外一個(gè)線程就會(huì)被直接踢到同步隊(duì)列中等待。 java代碼先編譯成字節(jié)碼,字節(jié)碼最后編譯成cpu指令,因此Java的多線程實(shí)現(xiàn)最終依賴于jvm和cpu的實(shí)現(xiàn) synchronized和volatile 我們先來(lái)討論一下volatile關(guān)鍵字的作用以及實(shí)現(xiàn)機(jī)制,每個(gè)線程看到的用volatile修飾的變量的值都是最新的,更深入的解釋就涉及到Java的內(nèi)存模型了,我們...
摘要:所以多線程條件下使用關(guān)鍵字的前提是對(duì)變量的寫(xiě)操作不依賴于變量的當(dāng)前值,而賦值操作很明顯滿足這一前提。在多線程環(huán)境下,正確使用關(guān)鍵字可以比直接使用更加高效而且代碼簡(jiǎn)潔,但是使用關(guān)鍵字也更容易出錯(cuò)。 volatile 作為 Java 語(yǔ)言的一個(gè)關(guān)鍵字,被看作是輕量級(jí)的 synchronized(鎖)。雖然 volatile 只具有synchronized 的部分功能,但是一般使用 vola...
摘要:今天開(kāi)始整理學(xué)習(xí)多線程的知識(shí),談?wù)勛钪匾膬蓚€(gè)關(guān)鍵字和。但是這樣一個(gè)過(guò)程比較慢,在使用多線程的時(shí)候就會(huì)出現(xiàn)問(wèn)題。有序性有序性是指多線程執(zhí)行結(jié)果的正確性。這種機(jī)制在多線程中會(huì)出現(xiàn)問(wèn)題,因此可以通過(guò)來(lái)禁止重排。 今天開(kāi)始整理學(xué)習(xí)多線程的知識(shí),談?wù)勛钪匾膬蓚€(gè)關(guān)鍵字:volatile和synchronized。 一、三個(gè)特性 1、原子性 所謂原子性操作就是指這些操作是不可中斷的,要么執(zhí)行過(guò)程...
時(shí)間:2017年07月09日星期日說(shuō)明:本文部分內(nèi)容均來(lái)自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)源碼:無(wú)學(xué)習(xí)源碼:https://github.com/zccodere/s... 第一章:課程簡(jiǎn)介 1-1 課程簡(jiǎn)介 課程目標(biāo)和學(xué)習(xí)內(nèi)容 共享變量在線程間的可見(jiàn)性 synchronized實(shí)現(xiàn)可見(jiàn)性 volatile實(shí)現(xiàn)可見(jiàn)性 指令重排序 as-if-seria...
閱讀 3412·2021-11-19 11:36
閱讀 2994·2021-09-27 13:34
閱讀 2056·2021-09-22 15:17
閱讀 2461·2019-08-30 13:49
閱讀 812·2019-08-26 13:58
閱讀 1416·2019-08-26 10:47
閱讀 2591·2019-08-23 18:05
閱讀 671·2019-08-23 14:25