亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
什麼是Java內(nèi)存模型?
問題:可見性和重新排序
發(fā)生在之前:核心保證
揮發(fā)性:不僅僅是“無緩存”
原子和種族條件
同步和JMM
最終字段和JMM
實(shí)用的要點(diǎn)
最終注意:不要滾動自己的同步
首頁 Java java教程 深入研究Java內(nèi)存模型

深入研究Java內(nèi)存模型

Aug 01, 2025 am 02:51 AM

Java存儲器模型(JMM)定義了線程如何與內(nèi)存,管理性更新的可見性,訂購和原子性相互作用。 2。如果沒有正確的同步,一個線程可能不會看到另一個由於緩存或指令重新排序而看到的更改。 3。發(fā)生的關(guān)係可確保通過程序順序,鎖,揮發(fā)性變量,線程啟動/加入建立可見性和訂購。 4。聲明可變的揮發(fā)性可確保可見性並防止重新排序,使其適用於標(biāo)誌,但不適合原子化合物操作。 5。諸如增量之類的原子操作需要原子素,同步塊或鎖以防止比賽條件。 6。同步塊提供了相互排除和保證,確保了共享數(shù)據(jù)的安全發(fā)布。 7.正確構(gòu)造的不變對像中的最終字段可在其他線程中可見,而無需其他同步。 8。最佳實(shí)踐包括使用揮發(fā)性來進(jìn)行簡單的標(biāo)誌,利用java.util.concurrent實(shí)用程序,更喜歡不變性,並避免依賴直觀的訂購。 9。在實(shí)際多線程條件下始終測試並發(fā)代碼,因?yàn)楦傎悧l件可能不會出現(xiàn)在單線程執(zhí)行中。 10。了解JMM可以通過設(shè)計(jì)而不是機(jī)會編寫正確的可預(yù)測的並發(fā)程序。

深入研究Java內(nèi)存模型

在使用Java(尤其是在並發(fā)或高性能應(yīng)用程序中)時,了解Java內(nèi)存模型(JMM)至關(guān)重要。它定義了線程如何通過內(nèi)存相互作用以及哪些行為在多線程代碼中是合法的。雖然Java通過垃圾收集來抽像大部分的內(nèi)存管理,但JMM控制著跨線程的可見性,訂購和原子能的可見性,並且弄錯了它可能會導(dǎo)致微妙的,難以挑剔的問題,例如種族條件,陳舊的數(shù)據(jù)或無限循環(huán)。

深入研究Java內(nèi)存模型

讓我們用實(shí)際術(shù)語分解Java內(nèi)存模型。


什麼是Java內(nèi)存模型?

Java內(nèi)存模型是Java語言規(guī)範(fàn)(JLS)中的規(guī)範(fàn),該規(guī)範(fàn)描述了線程如何與Java應(yīng)用程序中的內(nèi)存交互。它不能決定如何佈置內(nèi)存(例如堆或堆棧),而是定義了一個線程變量的更改何時必須對其他人可見。

深入研究Java內(nèi)存模型

關(guān)鍵想法:如果沒有正確的同步,一個線程可能看不到另一線程的更新,即使這些更新很久以前就發(fā)生了。

發(fā)生這種情況是因?yàn)椋?

深入研究Java內(nèi)存模型
  • 每個線程可能會在CPU寄存器或本地緩存中緩存變量。
  • 編譯器和處理器可以重新排序指令進(jìn)行優(yōu)化(只要保留單線程語義)即可。
  • JMM在這些行為上設(shè)定了邊界,以允許性能和可預(yù)測的並發(fā)性。

問題:可見性和重新排序

想像一下這種情況:

 //共享變量
int value = 0;
布爾準(zhǔn)備= false;

//線程1
值= 42;
準(zhǔn)備就緒= true;

//線程2
while(!準(zhǔn)備){
    // 旋轉(zhuǎn)
}
system.out.println(value); //什麼被打印出來?

您可能希望這打印42 。但是沒有同步,JMM允許:

  • 線程2永遠(yuǎn)不會退出循環(huán)(由於ready緩存)。
  • 線程2查看ready == true ,但value == 0 (如果重新排序或不沖洗寫作)。
  • 編譯器重新訂購value = 42ready = true 1中的編譯器。

這是JMM介入的地方 - 通過定義發(fā)生在關(guān)係之前的情況。


發(fā)生在之前:核心保證

在關(guān)係之前發(fā)生的是JMM的基石。如果一個動作發(fā)生在另一個動作之前,則第一個是可見的,並在第二個之前訂購。

建立發(fā)生之前的一些關(guān)鍵方法:

  • 程序順序規(guī)則:每個線程都會在操作之間以代碼出現(xiàn)的順序出現(xiàn)在操作之間。
  • 監(jiān)視器鎖定規(guī)則:在同一監(jiān)視器上的每個後續(xù)鎖之前發(fā)生在監(jiān)視器上的解鎖。
  • 揮發(fā)性變量規(guī)則:將其寫入揮發(fā)性變量發(fā)生 - 在隨後的每個讀取同一揮發(fā)性變量之前。
  • 線程啟動規(guī)則:調(diào)用thread.start()發(fā)生 - 在開始線程中的任何操作之前。
  • 線程JOIN規(guī)則:線程中的所有操作發(fā)生在該線程的返回之前join() 。

返回我們的示例 - 如果我們ready就緒揮發(fā)性

揮發(fā)性布爾值準(zhǔn)備= false;

現(xiàn)在:

  • 寫入value寫入之前 - 寫入ready (程序順序)。
  • 在讀取ready 2(揮發(fā)性規(guī)則)之前,寫入為ready就緒。
  • 因此,線程2中的value的讀取從線程1中看到寫入。

結(jié)果:保證打印42 。


揮發(fā)性:不僅僅是“無緩存”

許多開發(fā)人員認(rèn)為volatile只是阻止了緩存 - 但它做了兩件事:

  1. 確??梢娦?/strong>:文字立即被沖洗到主內(nèi)存,讀取來自主內(nèi)存。
  2. 防止重新排序:JVM和CPU不會重新排序讀取/寫入揮發(fā)性訪問。

具體來說:

  • 任何先前的讀/寫入都無法重新排序揮發(fā)性變量的讀取。
  • 揮發(fā)性變量的寫入無法通過隨後的任何讀/寫入重新排序。

這使得volatile對標(biāo)誌和狀態(tài)指標(biāo)有用,但對於諸如count類的複合操作不足


原子和種族條件

JMM還定義了哪些操作是原子。

保證原子:

  • 讀/寫入intreference類型。
  • 讀/寫入volatile longvolatile double (因?yàn)樗鼈兘?jīng)過特殊對待)。

不是原子:

  • 常規(guī)讀取/寫入longdouble (可以分為兩個32位操作,儘管在大多數(shù)現(xiàn)代JVM上,它們實(shí)際上是原子能的)。
  • 甚至在int上,諸如i (讀取模式寫入)之類的複合動作。

因此,即使可見變量,您仍然可以擁有種族條件:

揮發(fā)性int計(jì)數(shù)器= 0;

//在多個線程中:
櫃檯 ; //不是原子!需要同步。

在這種情況下,使用AtomicInteger , synchronizedlock 。


同步和JMM

synchronized塊的作用不僅僅是相互排斥 - 它們建立了發(fā)生的關(guān)係。

當(dāng)線程退出synchronized塊時:

  • 在下一個線程獲取它之前,所有人都在發(fā)布監(jiān)視器之前寫下。

例子:

對象鎖=新對象();
int data = 0;
布爾準(zhǔn)備= false;

//線程1
同步(鎖){
    數(shù)據(jù)= 42;
    準(zhǔn)備就緒= true;
}

//線程2
同步(鎖){
    如果(準(zhǔn)備就緒){
        system.out.println(data); //保證看到42
    }
}

即使沒有volatile ,同步塊也會在鏈條前創(chuàng)建一個發(fā)生的鏈接,從而確??梢娦浴?/p>


最終字段和JMM

JMM經(jīng)常被忽視的部分是它如何處理final字段。

關(guān)鍵點(diǎn):正確構(gòu)造的最終字段總是在沒有同步的情況下可見其他線程

例子:

公共類不成熟的對象{
    最終int值;
    最終字符串名稱;

    public immableableObject(int value,string name){
        this.value = value;
        this.name = name;
    }
}

如果線程安全地發(fā)布了一個ImmutableObject的實(shí)例(例如,通過正確構(gòu)造的列表或靜態(tài)字段),其他線程也會看到valuename的正確值 - 即使無同步共享對像也是如此。

但這僅在以下情況下起作用:

  • 對物體的引用在施工過程中不會逸出。
  • 該物體有效地不變或真正不變。

實(shí)用的要點(diǎn)

編寫正確的並發(fā)Java代碼:

  • 使用揮發(fā)性進(jìn)行簡單標(biāo)誌或狀態(tài)變量。
  • 使用同步,重新進(jìn)入原子類進(jìn)行複合操作。
  • 在可能的情況下更喜歡不可變的物體- 它們是設(shè)計(jì)的線程安全。
  • 了解局部變量是線程安全的(每個線程都有其自己的堆棧),但共享對像不是。
  • 避免依靠“直覺”訂購 - 在規(guī)則之前使用正確性。

最終注意:不要滾動自己的同步

JMM很複雜,低級內(nèi)存語義很容易犯錯。在大多數(shù)情況下:

  • 使用java.util.concurrent的高級並發(fā)公用事業(yè): ConcurrentHashMapAtomicInteger , BlockingQueue等。
  • 設(shè)計(jì)的不變性和無狀態(tài)。
  • 在實(shí)際並發(fā)下測試 - 種族條件通常不會出現(xiàn)在單線程測試中。

了解JMM不會消除錯誤,但是它可以幫助您編寫設(shè)計(jì)正確的代碼,而不是運(yùn)氣。

基本上,這是使Java並發(fā)既強(qiáng)大又危險的基礎(chǔ)。

以上是深入研究Java內(nèi)存模型的詳細(xì)內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java中的'枚舉”類型是什麼? Java中的'枚舉”類型是什麼? Jul 02, 2025 am 01:31 AM

Java中的枚舉(enum)是一種特殊的類,用於表示固定數(shù)量的常量值。 1.使用enum關(guān)鍵字定義;2.每個枚舉值都是該枚舉類型的公共靜態(tài)最終實(shí)例;3.可以包含字段、構(gòu)造函數(shù)和方法,為每個常量添加行為;4.可在switch語句中使用,支持直接比較,並提供name()、ordinal()、values()和valueOf()等內(nèi)置方法;5.枚舉可提升代碼的類型安全性、可讀性和靈活性,適用於狀態(tài)碼、顏色或星期等有限集合場景。

界面隔離原理是什麼? 界面隔離原理是什麼? Jul 02, 2025 am 01:24 AM

接口隔離原則(ISP)要求不強(qiáng)制客戶端依賴未使用的接口。其核心是用多個小而精的接口替代大而全的接口。違反該原則的表現(xiàn)包括:類實(shí)現(xiàn)接口時拋出未實(shí)現(xiàn)異常、存在大量無效方法實(shí)現(xiàn)、無關(guān)功能被強(qiáng)行歸入同一接口。應(yīng)用方法包括:按常用方法組劃分接口、依據(jù)客戶端使用拆分接口、必要時使用組合替代多接口實(shí)現(xiàn)。例如將包含打印、掃描、傳真方法的Machine接口拆分為Printer、Scanner和FaxMachine。在小型項(xiàng)目或所有客戶端均使用全部方法時可適當(dāng)放寬規(guī)則。

現(xiàn)代爪哇的異步編程技術(shù) 現(xiàn)代爪哇的異步編程技術(shù) Jul 07, 2025 am 02:24 AM

Java支持異步編程的方式包括使用CompletableFuture、響應(yīng)式流(如ProjectReactor)以及Java19 中的虛擬線程。 1.CompletableFuture通過鍊式調(diào)用提升代碼可讀性和維護(hù)性,支持任務(wù)編排和異常處理;2.ProjectReactor提供Mono和Flux類型實(shí)現(xiàn)響應(yīng)式編程,具備背壓機(jī)制和豐富的操作符;3.虛擬線程減少並發(fā)成本,適用於I/O密集型任務(wù),與傳統(tǒng)平臺線程相比更輕量且易於擴(kuò)展。每種方式均有適用場景,應(yīng)根據(jù)需求選擇合適工具並避免混合模型以保持簡潔性

Java中可呼叫和可運(yùn)行的差異 Java中可呼叫和可運(yùn)行的差異 Jul 04, 2025 am 02:50 AM

Callable和Runnable在Java中主要有三點(diǎn)區(qū)別。第一,Callable的call()方法可以返回結(jié)果,適合需要返回值的任務(wù),如Callable;而Runnable的run()方法無返回值,適用於無需返回的任務(wù),如日誌記錄。第二,Callable允許拋出checked異常,便於錯誤傳遞;而Runnable必須在內(nèi)部處理異常。第三,Runnable可直接傳給Thread或ExecutorService,而Callable只能提交給ExecutorService,並返回Future對像以

在Java中使用枚舉的最佳實(shí)踐 在Java中使用枚舉的最佳實(shí)踐 Jul 07, 2025 am 02:35 AM

在Java中,枚舉(enum)適合表示固定常量集合,最佳實(shí)踐包括:1.用enum表示固定狀態(tài)或選項(xiàng),提升類型安全和可讀性;2.為枚舉添加屬性和方法以增強(qiáng)靈活性,如定義字段、構(gòu)造函數(shù)、輔助方法等;3.使用EnumMap和EnumSet提高性能和類型安全性,因其基於數(shù)組實(shí)現(xiàn)更高效;4.避免濫用enum,如動態(tài)值、頻繁變更或複雜邏輯場景應(yīng)使用其他方式替代。正確使用enum能提升代碼質(zhì)量並減少錯誤,但需注意其適用邊界。

了解Java Nio及其優(yōu)勢 了解Java Nio及其優(yōu)勢 Jul 08, 2025 am 02:55 AM

JavaNIO是Java1.4引入的新型IOAPI,1)面向緩衝區(qū)和通道,2)包含Buffer、Channel和Selector核心組件,3)支持非阻塞模式,4)相比傳統(tǒng)IO更高效處理並發(fā)連接。其優(yōu)勢體現(xiàn)在:1)非阻塞IO減少線程開銷,2)Buffer提升數(shù)據(jù)傳輸效率,3)Selector實(shí)現(xiàn)多路復(fù)用,4)內(nèi)存映射加快文件讀寫。使用時需注意:1)Buffer的flip/clear操作易混淆,2)非阻塞下需手動處理不完整數(shù)據(jù),3)Selector註冊需及時取消,4)NIO並非適用於所有場景。

探索Java中不同的同步機(jī)制 探索Java中不同的同步機(jī)制 Jul 04, 2025 am 02:53 AM

Javaprovidesmultiplesynchronizationtoolsforthreadsafety.1.synchronizedblocksensuremutualexclusionbylockingmethodsorspecificcodesections.2.ReentrantLockoffersadvancedcontrol,includingtryLockandfairnesspolicies.3.Conditionvariablesallowthreadstowaitfor

Java Classloader在內(nèi)部如何工作 Java Classloader在內(nèi)部如何工作 Jul 06, 2025 am 02:53 AM

Java的類加載機(jī)制通過ClassLoader實(shí)現(xiàn),其核心工作流程分為加載、鏈接和初始化三個階段。加載階段由ClassLoader動態(tài)讀取類的字節(jié)碼並創(chuàng)建Class對象;鏈接包括驗(yàn)證類的正確性、為靜態(tài)變量分配內(nèi)存及解析符號引用;初始化則執(zhí)行靜態(tài)代碼塊和靜態(tài)變量賦值。類加載採用雙親委派模型,優(yōu)先委託父類加載器查找類,依次嘗試Bootstrap、Extension和ApplicationClassLoader,確保核心類庫安全且避免重複加載。開發(fā)者可自定義ClassLoader,如URLClassL

See all articles