Java關(guān)鍵字volatile和synchronized作用和區(qū)別
volatile是變量修飾符,而synchronized則是作用于一段代碼或方法;如下三句get代碼:
int i1;
int geti1() {return i1;}
volatile int i2;
int geti2() {return i2;}
int i3;
synchronized int geti3() {return i3;}
geti1() 得到存儲在當前線程中i1的數(shù)值。多個線程有多個i1變量拷貝,而且這些i1之間可以相互不同。換句話說,另一個線程可能已經(jīng)改變了它線程內(nèi)的i1值,而這個值可以和當前線程中的i1值不相同。 在Java內(nèi)存模型中,有main memory(主內(nèi)存區(qū)域),這里存放了變量目前的“準確值”,每個線程也有自己的memory(例如寄存器)。為了性能,一個線程會在自己的memory中保存要訪問的變量的副本。這樣就會出現(xiàn)同一個變量在某個瞬間,在一個線程的memory中的值可能與另外一個線程memory的值,或者main memory的值不一致的情況。因此實際上存在一種可能:main memory的值i1值是1,線程1里的i1是2,線程2里的i1值是3,這在線程1和線程2都改變了他們各自的i1值,而且這個改變還沒來得及傳給main memory 或其他線程時就會發(fā)生。
geti2() 得到的是main memory的i2數(shù)值。一個變量聲明為volatile,就意味著這個變量是隨時會被其他線程修改的,因此不能將它cache在線程memory中。換句話說,一個變量經(jīng)過volatile修飾后在所有線程中必須是同步的,任何線程中改變了它的值,所有其他線程立即獲得了相同的值。所以,volatile修飾的變量存取時比一般變量消耗的資源要多一點,因為線程有它自己的變量拷貝更為高效。
geti3()方法被synchronized修飾,用synchronized來修飾一個方法或者一個貸款的時候,能夠保證在同一時刻最多只有一個線程執(zhí)行該段代碼。既然volatile關(guān)鍵字已經(jīng)實現(xiàn)了線程間數(shù)據(jù)同步,又要synchronized干嘛呢?當兩個并發(fā)線程訪問同一個對象object中的這個synchronized(this)同步貸款時,一個時間內(nèi)只能有一個線程得到執(zhí)行。另一個線程必須等待當前線程執(zhí)行完這個代碼塊才能執(zhí)行該代碼塊。然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。尤其關(guān)鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時候,其他線程對object中所有其他synchronized(this)同步代碼塊的訪問將被阻塞。當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖,結(jié)果,其他線程對該對象所有同步代碼部分的訪問都被暫時阻塞。
總結(jié)一下區(qū)別:
一,volatile是變量修飾符,而synchronized則作用于一段代碼或者方法。
二,volatile只是在線程內(nèi)存和main memory(主內(nèi)存)間同步某個變量的值;而synchronized通過鎖定和解鎖某個監(jiān)視器同步所有變量的值。顯然synchronized要比volatile消耗更多資源。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- 深入理解java中的synchronized關(guān)鍵字
- 詳解Java中synchronized關(guān)鍵字的死鎖和內(nèi)存占用問題
- Java中synchronized關(guān)鍵字修飾方法同步的用法詳解
- java多線程編程之使用Synchronized關(guān)鍵字同步類方法
- 舉例講解Java中synchronized關(guān)鍵字的用法
- 實例解析Java中的synchronized關(guān)鍵字與線程安全問題
- 深入了解Java中Synchronized關(guān)鍵字的實現(xiàn)原理
- java基本教程之synchronized關(guān)鍵字 java多線程教程
- java synchronized關(guān)鍵字的用法
- Java中synchronized關(guān)鍵字鎖的力度與位置示例詳解
相關(guān)文章
springBoot?@Scheduled實現(xiàn)多個任務同時開始執(zhí)行
這篇文章主要介紹了springBoot?@Scheduled實現(xiàn)多個任務同時開始執(zhí)行,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
解決Spring Cloud feign GET請求無法用實體傳參的問題
這篇文章主要介紹了解決Spring Cloud feign GET請求無法用實體傳參的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01
spring?boot整合mongo查詢converter異常排查記錄
這篇文章主要為大家介紹了spring?boot整合mongo查詢時拋出converter異常的排查解決記錄,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-03-03
淺析SpringBoot中使用thymeleaf找不到.HTML文件的原因
這篇文章主要介紹了SpringBoot中使用thymeleaf找不到.HTML文件的原因分析,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
BufferedReader中read()方法和readLine()方法的使用
這篇文章主要介紹了BufferedReader中read()方法和readLine()方法的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04
Spring?Boot?利用?XML?方式整合?MyBatis
這篇文章主要介紹了Spring?Boot?利用?XML?方式整合?MyBatis,文章圍繞主題的相關(guān)資料展開詳細的內(nèi)容介紹,具有一定的參考價值,組要的小伙伴可以參考一下2022-05-05

