欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中volatile關(guān)鍵字的線程的可見性、有序性詳解

 更新時間:2024年01月11日 10:29:12   作者:好奇的7號  
這篇文章主要介紹了Java中volatile關(guān)鍵字的線程的可見性、有序性詳解,在juc多線程并發(fā)編程中,常常需要關(guān)注線程的"可見性"與"有序性",本文將詳細介紹這兩部分內(nèi)容,以及volatile關(guān)鍵字的使用,需要的朋友可以參考下

引言

在juc多線程并發(fā)編程中,常常需要關(guān)注線程的“可見性”與“有序性”。本文將詳細介紹這兩部分內(nèi)容,以及volatile關(guān)鍵字的使用。

閱讀本文前需要一些jvm運行時內(nèi)存、進程與線程、共享內(nèi)存、鎖等相關(guān)知識。

1、可見性

1.1 定義

當一個對象在多個內(nèi)存中都存在副本時,如果一個內(nèi)存修改了共享變量,其它線程也應(yīng)該能夠看到被修改后的值。

1.2 解釋

解釋這句話,首先我們要知道,進程是操作系統(tǒng)分配資源的最小單位,在每個進程里,都包含有數(shù)據(jù)共享的區(qū)域(例如其中有成員變量、堆、靜態(tài)常量等,詳情查閱jvm運行時內(nèi)存),并可能包含多個線程。 在jvm底層,每個線程想要操作某個共享變量時,不能夠直接操作共享區(qū)域的“主存”,而是要先把數(shù)據(jù)從主存讀到線程自己的高速緩存中,再進行操作,再賦值回去。

“具體來說,當一個線程要讀取某個變量的值時,它首先檢查自己的工作緩存中是否存在該變量的副本。 如果存在,則直接讀取副本的值; 如果不存在,則從主內(nèi)存中獲取該變量的最新值,并將其復(fù)制到自己的工作緩存中。 類似地,當一個線程要修改某個變量的值時,它首先會在自己的工作緩存中修改副本,再根據(jù)一定的策略將變化同步回主內(nèi)存。”

那么可見性的概念相應(yīng)而來:多個線程都存了同一個對象副本,如果此時有一個內(nèi)存修改了共享變量,其他的線程應(yīng)該能夠“看到”,而不是傻b一樣仍舊拿著自己緩存里的值操作了。

1.3 實例說明

例如下面情況,如果main 線程對 run 變量的修改對于 t 線程不可見,導(dǎo)致了 t 線程無法停止:

其原因是t線程頻繁從主內(nèi)存中讀取 run 的值,JIT 編譯器會將 run 的值緩存至自己工作內(nèi)存中的高速緩存中, 減少對主存中 run 的訪問。 那么,當主線程(也就是其他線程)把run變?yōu)閒alse,由于子線程t(當前線程)仍然從高速緩存里讀的run,會認為run并沒有改變,從而邏輯出現(xiàn)問題。

1.4 解決方法:volatile(易變關(guān)鍵字)

作用:volatile可以用來修飾成員變量和靜態(tài)成員變量,他可以避免線程從自己的工作緩存中查找變量的值,必須到主存中獲取它的值。(關(guān)鍵點)

然而volatile并不能保證原子性,例如不加鎖的多線程執(zhí)行函數(shù),對成員變量i進行i++ i--,最后得到的結(jié)果i不一定是不變的。 因為volatile關(guān)鍵字,只能讓該線程在使用數(shù)據(jù)前強制從主存讀取,但讀取后是否發(fā)生改變是看不見的。如果有別的線程在該線程讀取后成功改變了共享內(nèi)存的值,還是會發(fā)生指令交錯。

2、有序性

在多線程環(huán)境下,由于編譯器和處理器對指令進行優(yōu)化和重排序,可能會導(dǎo)致操作的執(zhí)行順序發(fā)生改變,從而違反了代碼編寫的原始順序。

為了保證有序性,可以使用以下方法:

使用volatile關(guān)鍵字:對關(guān)鍵的共享變量使用volatile關(guān)鍵字進行聲明,以確保對該變量的寫操作立即對其他線程可見。

使用synchronized關(guān)鍵字或Lock機制:通過使用同步塊或鎖來保護共享資源的讀寫操作,確保線程之間的有序訪問。

使用原子類:Java提供了一些原子類(如AtomicInteger、AtomicLong等)來進行原子操作,這些原子類的方法能夠保證操作的原子性、可見性和有序性。

簡單來說volatile避免了指令重排,也就避免了多線程中可能產(chǎn)生的問題。

到此這篇關(guān)于Java中volatile關(guān)鍵字的線程的可見性、有序性詳解的文章就介紹到這了,更多相關(guān)volatile的線程的可見性、有序性內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java Swing實現(xiàn)餐廳點餐系統(tǒng)源碼(收藏版)

    Java Swing實現(xiàn)餐廳點餐系統(tǒng)源碼(收藏版)

    這篇文章主要介紹了Java Swing實現(xiàn)餐廳點餐系統(tǒng)源碼,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • java實現(xiàn)Api接口加密通信方式

    java實現(xiàn)Api接口加密通信方式

    這篇文章主要介紹了java實現(xiàn)Api接口加密通信方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Spring實現(xiàn)文件上傳的配置詳解

    Spring實現(xiàn)文件上傳的配置詳解

    這篇文章將為大家詳細說明一下spring上傳文件如何配置,以及從request請求中解析到文件流的原理,文中示例代碼講解詳細,感興趣的可以了解一下
    2022-08-08
  • Java調(diào)用opencv IDEA環(huán)境配置的教程詳解

    Java調(diào)用opencv IDEA環(huán)境配置的教程詳解

    這篇文章主要為大家詳細介紹了Java調(diào)用opencv IDEA環(huán)境配置的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-03-03
  • SpringCloud配置客戶端ConfigClient接入服務(wù)端

    SpringCloud配置客戶端ConfigClient接入服務(wù)端

    這篇文章主要為大家介紹了SpringCloud配置客戶端ConfigClient接入服務(wù)端,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • Java利用JSONPath操作JSON數(shù)據(jù)的技術(shù)指南

    Java利用JSONPath操作JSON數(shù)據(jù)的技術(shù)指南

    JSONPath?是一種強大的工具,用于查詢和操作?JSON?數(shù)據(jù),類似于?SQL?的語法,它為處理復(fù)雜的?JSON?數(shù)據(jù)結(jié)構(gòu)提供了簡單且高效的解決方案,本文將介紹?JSONPath?的基本語法,并通過詳細的?Java?示例展示其實際應(yīng)用,需要的朋友可以參考下
    2025-04-04
  • 代理模式:JAVA靜態(tài)代理和動態(tài)代理的實例和實現(xiàn)詳解

    代理模式:JAVA靜態(tài)代理和動態(tài)代理的實例和實現(xiàn)詳解

    這篇文章主要給大家介紹了關(guān)于Java靜態(tài)代理和動態(tài)代理的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-08-08
  • Java移除無效括號的方法實現(xiàn)

    Java移除無效括號的方法實現(xiàn)

    本文主要介紹了Java移除無效括號的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • SpringCloud Alibaba使用Seata處理分布式事務(wù)的技巧

    SpringCloud Alibaba使用Seata處理分布式事務(wù)的技巧

    在傳統(tǒng)的單體項目中,我們使用@Transactional注解就能實現(xiàn)基本的ACID事務(wù)了,隨著微服務(wù)架構(gòu)的引入,需要對數(shù)據(jù)庫進行分庫分表,每個服務(wù)擁有自己的數(shù)據(jù)庫,這樣傳統(tǒng)的事務(wù)就不起作用了,那么我們?nèi)绾伪WC多個服務(wù)中數(shù)據(jù)的一致性呢?跟隨小編一起通過本文了解下吧
    2021-06-06
  • Java 基于AQS實現(xiàn)一個同步器

    Java 基于AQS實現(xiàn)一個同步器

    這篇文章主要介紹了如何基于AQS實現(xiàn)一個同步器,幫助大家更好的理解和學習Java并發(fā),感興趣的朋友可以了解下
    2020-09-09

最新評論