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() 得到存儲在當(dāng)前線程中i1的數(shù)值。多個線程有多個i1變量拷貝,而且這些i1之間可以相互不同。換句話說,另一個線程可能已經(jīng)改變了它線程內(nèi)的i1值,而這個值可以和當(dāng)前線程中的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干嘛呢?當(dāng)兩個并發(fā)線程訪問同一個對象object中的這個synchronized(this)同步貸款時,一個時間內(nèi)只能有一個線程得到執(zhí)行。另一個線程必須等待當(dāng)前線程執(zhí)行完這個代碼塊才能執(zhí)行該代碼塊。然而,當(dāng)一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。尤其關(guān)鍵的是,當(dāng)一個線程訪問object的一個synchronized(this)同步代碼塊時候,其他線程對object中所有其他synchronized(this)同步代碼塊的訪問將被阻塞。當(dāng)一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖,結(jié)果,其他線程對該對象所有同步代碼部分的訪問都被暫時阻塞。
總結(jié)一下區(qū)別:
一,volatile是變量修飾符,而synchronized則作用于一段代碼或者方法。
二,volatile只是在線程內(nèi)存和main memory(主內(nèi)存)間同步某個變量的值;而synchronized通過鎖定和解鎖某個監(jiān)視器同步所有變量的值。顯然synchronized要比volatile消耗更多資源。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 深入理解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)鍵字實現(xiàn)簡單同步操作示例
- 舉例講解Java中synchronized關(guān)鍵字的用法
- 實例解析Java中的synchronized關(guān)鍵字與線程安全問題
- Java關(guān)鍵字synchronized基本使用詳解
相關(guān)文章
SpringBoot?@GroupSequenceProvider注解實現(xiàn)bean多屬性聯(lián)合校驗的示例代碼
這篇文章主要介紹了SpringBoot?@GroupSequenceProvider注解實現(xiàn)bean多屬性聯(lián)合校驗,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08詳解SpringBoot?統(tǒng)一后端返回格式的方法
今天我們來聊一聊在基于SpringBoot前后端分離開發(fā)模式下,如何友好的返回統(tǒng)一的標(biāo)準格式以及如何優(yōu)雅的處理全局異常,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2022-05-05Java文件讀寫IO/NIO及性能比較詳細代碼及總結(jié)
這篇文章主要介紹了Java文件讀寫IO/NIO及性能比較詳細代碼及總結(jié),具有一定借鑒價值,需要的朋友可以參考下。2017-12-12基于spring?data?jpa?@query返回map的踩坑記錄
這篇文章主要介紹了基于spring?data?jpa?@query返回map的踩坑記錄,具有很好的參考價值,如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11SpringBoot項目中訪問HTML頁面的實現(xiàn)示例
本文主要介紹了SpringBoot項目中訪問HTML頁面的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08SpringCloud Alibaba Seata (收藏版)
Seata是一款開源的分布式事務(wù)解決方案,致力于在微服務(wù)架構(gòu)在提供高性能和簡單一樣的分布式事務(wù)服務(wù)。這篇文章主要介紹了SpringCloud Alibaba Seata 的相關(guān)知識,需要的朋友可以參考下2020-10-10