真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java內(nèi)存模型以及線(xiàn)程安全的可見(jiàn)性問(wèn)題是怎樣的

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)Java內(nèi)存模型以及線(xiàn)程安全的可見(jiàn)性問(wèn)題是怎樣的,文章內(nèi)容豐富且以專(zhuān)業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

因?yàn)榕驼嬲\(chéng),有更多的客戶(hù)和我們聚集在一起,為了共同目標(biāo),成都創(chuàng)新互聯(lián)公司在工作上密切配合,從創(chuàng)業(yè)型企業(yè)到如今不斷成長(zhǎng),要感謝客戶(hù)對(duì)我們的高要求,讓我們敢于面對(duì)挑戰(zhàn),才有今天的進(jìn)步與發(fā)展。從網(wǎng)站到成都微信小程序,軟件開(kāi)發(fā),app軟件定制開(kāi)發(fā),10余年企業(yè)網(wǎng)站建設(shè)服務(wù)經(jīng)驗(yàn),為企業(yè)提供網(wǎng)站設(shè)計(jì),綿陽(yáng)服務(wù)器托管一條龍服務(wù).為企業(yè)提供成都全網(wǎng)營(yíng)銷(xiāo)推廣,按需求定制設(shè)計(jì),原創(chuàng)設(shè)計(jì),10余年品質(zhì),值得您的信賴(lài).

Java內(nèi)存模型 VS JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)

首先Java內(nèi)存模型(JMM)和JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)并不是一個(gè)東西,許多介紹Java內(nèi)存模型的文章描述的堆,方法區(qū),Java虛擬機(jī)棧,本地方法棧,程序計(jì)數(shù)器這東西并不是Java內(nèi)存模型的內(nèi)容而是JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的內(nèi)容。
要理解二者的區(qū)別就要了解《Java虛擬機(jī)規(guī)范》和《Java語(yǔ)言規(guī)范》。我們知道Java虛擬機(jī)上并不知只有Java語(yǔ)言,像JRuby, ,Scala,Kotlin,Groovy等也都運(yùn)行在Java虛擬機(jī)上,而這些語(yǔ)言想要在Java虛擬機(jī)上運(yùn)行就要遵守《Java虛擬機(jī)規(guī)范》,而JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)就是《Java虛擬機(jī)規(guī)范》的內(nèi)容。而《Java語(yǔ)言規(guī)范》就只是針對(duì)Java語(yǔ)言的規(guī)范,它對(duì)Java內(nèi)存模型做了詳細(xì)的描述。
Java內(nèi)存模型以及線(xiàn)程安全的可見(jiàn)性問(wèn)題是怎樣的

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

要了解Java內(nèi)存模型,首先要了解什么是內(nèi)存模型,之間在CPU緩存和內(nèi)存屏障 中我們了解到緩存一致性問(wèn)題以及處理器優(yōu)化的指令重排序問(wèn)題。為了保證并發(fā)編程中可以滿(mǎn)足原子性、可見(jiàn)性及有序性。有一個(gè)重要的概念,那就是——內(nèi)存模型。它解決了 CPU 多級(jí)緩存、處理器優(yōu)化、指令重排等導(dǎo)致的內(nèi)存訪問(wèn)問(wèn)題,保證了并發(fā)場(chǎng)景下的一致性、原子性和有序性。而Java內(nèi)存模型就是解決由于多線(xiàn)程通過(guò)共享內(nèi)存進(jìn)行通信時(shí),存在的本地內(nèi)存數(shù)據(jù)不一致、編譯器會(huì)對(duì)代碼指令重排序、處理器會(huì)對(duì)代碼亂序執(zhí)行等帶來(lái)的問(wèn)題的一種規(guī)范。目的是保證并發(fā)編程場(chǎng)景中的原子性、可見(jiàn)性和有序性。
Java內(nèi)存模型可以分為線(xiàn)程棧(或者叫工作內(nèi)存,它是每個(gè)線(xiàn)程所獨(dú)有的)和堆(或者叫主內(nèi)存,與JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)的堆并不是一個(gè)概念,它是所線(xiàn)程共享的),其大致邏輯圖如下:
Java內(nèi)存模型以及線(xiàn)程安全的可見(jiàn)性問(wèn)題是怎樣的

JMM中的具體內(nèi)容

Shared Variables定義

可以在線(xiàn)程之間共享的內(nèi)存稱(chēng)為共享內(nèi)存或堆內(nèi)存
所有實(shí)例字段,靜態(tài)字段和數(shù)組元素都存儲(chǔ)在共享內(nèi)存,這些字段和數(shù)組就是共享變量
沖突:如果至少有一個(gè)訪問(wèn)是寫(xiě)操作,那么對(duì)同一個(gè)變量的兩次訪問(wèn)是沖突的

這些能被多個(gè)線(xiàn)程訪問(wèn)的共享變量是內(nèi)存模型規(guī)范的對(duì)象

線(xiàn)程間操作

線(xiàn)程間操作指一個(gè)線(xiàn)程執(zhí)行的操作可被其他線(xiàn)程感知或被其他線(xiàn)程直接影響
Java內(nèi)存模型只描述線(xiàn)程間操作,不描述線(xiàn)程內(nèi)操作,線(xiàn)程內(nèi)操作按照線(xiàn)程內(nèi)語(yǔ)義執(zhí)行
線(xiàn)程間操作有:

  • read操作(一般讀,即非volatile讀)

  • write操作(一般寫(xiě),即非volatile寫(xiě))

  • volatile read

  • volatile write

  • Lock,Unlock

  • 線(xiàn)程的第一個(gè)和最后一個(gè)操作

  • 外部操作

對(duì)同步規(guī)則的定義
  • 對(duì)volatile變量V的寫(xiě)入,與所有其它線(xiàn)程后續(xù)對(duì)V的讀同步

  • 對(duì)于監(jiān)視器m的解鎖與所有后續(xù)操作對(duì)于m的加鎖同步

  • 對(duì)于每個(gè)屬性寫(xiě)入默認(rèn)值(0,false, null)與每個(gè)線(xiàn)程對(duì)其進(jìn)行的操作同步

  • 啟動(dòng)線(xiàn)程的操作與線(xiàn)程中的第一個(gè)操作同步

  • 線(xiàn)程T2的最后操作與線(xiàn)程T1發(fā)現(xiàn)T2已經(jīng)結(jié)束同步

  • 如果線(xiàn)程T1中斷了T2,那么線(xiàn)程T1的中斷操作與其他所有線(xiàn)程發(fā)現(xiàn)T2被中斷了同步

happens-before先行發(fā)生原則

happens-before關(guān)系用于描述兩個(gè)有沖突的動(dòng)作之間的順序,如果一個(gè)action happens before 另一個(gè)action,則第一個(gè)操作對(duì)第二個(gè)操作可見(jiàn),JVM需要實(shí)現(xiàn)如下happens-before規(guī)則:

  • 某個(gè)線(xiàn)程中的每個(gè)動(dòng)作都happens-before該線(xiàn)程中該動(dòng)作后面的操作

  • 某個(gè)管程中的unlock動(dòng)作happens-before同一個(gè)管程上后續(xù)的lock操作

  • 對(duì)某個(gè)volatile字段的寫(xiě)操作happens-before每個(gè)后續(xù)對(duì)該volatile字段的讀操作

  • 在某個(gè)對(duì)象上調(diào)用start()方法happens-before被啟動(dòng)線(xiàn)程的任意動(dòng)作

  • 如果在線(xiàn)程t1中成功執(zhí)行了t2.join(),則t2中的所有操作對(duì)t1可見(jiàn)

  • 如果某個(gè)動(dòng)作a happens-before動(dòng)作b,且b happens-before動(dòng)作c,則a happens-before c

final在JMM中的處理

final在該對(duì)象的構(gòu)造函數(shù)中設(shè)置對(duì)象的字段,當(dāng)線(xiàn)程看到該對(duì)象時(shí),將始終看到該對(duì)象的final字段的正確構(gòu)造版本。如果在構(gòu)造函數(shù)中設(shè)置字段后發(fā)生讀取,則會(huì)看到該final字段分配的值,否則它將看到默認(rèn)值。讀取該對(duì)象的final成員變量之前,先要讀取共享對(duì)象。
通常被 static final修飾的字段, 不能被修改。然而System.in, System.out, System.err被static final修飾卻可以修改,遺留問(wèn)題,必須通過(guò)set方法改變,我們將這些字段稱(chēng)為寫(xiě)保護(hù),以區(qū)別于普通final字段。

Word Tearing字節(jié)處理

有些處理器(尤其是早期的Alphas處理器)沒(méi)有提供寫(xiě)單個(gè)字節(jié)的功能。在這樣的處理器上更新byte數(shù)組,若只是簡(jiǎn)單的讀取整個(gè)內(nèi)容,更新對(duì)應(yīng)的字節(jié),然后將整個(gè)內(nèi)容再寫(xiě)回內(nèi)存,將是不合法的。這個(gè)問(wèn)題有時(shí)候被稱(chēng)為“字分裂(word tearing)”,更新字節(jié)有難度的處理器,就需要尋求其他方式來(lái)解決。因此,編程人員需要注意,盡量不要對(duì)byte[]中的元素進(jìn)行重新賦值,更不要在多線(xiàn)程中這樣做。

可見(jiàn)性問(wèn)題

可見(jiàn)性:主要是指一個(gè)線(xiàn)程對(duì)共享變量的寫(xiě)入可以被后續(xù)另一個(gè)線(xiàn)程讀取到,也就說(shuō)一個(gè)線(xiàn)程對(duì)共享變量的操作對(duì)另一個(gè)線(xiàn)程是可見(jiàn)的。
而可見(jiàn)性問(wèn)題就是指一個(gè)線(xiàn)程對(duì)共享變量進(jìn)行了寫(xiě)入而其他的線(xiàn)程卻無(wú)法讀取到該線(xiàn)程寫(xiě)入的結(jié)果,根據(jù)以下工作內(nèi)存的緩存的模型我們可以知道,造成可見(jiàn)性的問(wèn)題主要有兩方面,一個(gè)是數(shù)據(jù)在寫(xiě)入的時(shí)候只是寫(xiě)入了緩存而沒(méi)有寫(xiě)入主內(nèi)存,一個(gè)是數(shù)據(jù)在讀取的時(shí)候只是從緩存中讀取到了數(shù)據(jù)而沒(méi)有從主內(nèi)存讀取數(shù)據(jù)。
Java內(nèi)存模型以及線(xiàn)程安全的可見(jiàn)性問(wèn)題是怎樣的

可見(jiàn)性問(wèn)題的解決方法 — volatile關(guān)鍵字

volatile關(guān)鍵字可以保證一個(gè)線(xiàn)程對(duì)共享變量的修改,能夠及時(shí)的被其他線(xiàn)程看到。
根據(jù)JMM中的happen before 和同步原則:

  • 對(duì)某個(gè)volatile字段的寫(xiě)操作happens-before每個(gè)后續(xù)對(duì)該volatile字段的讀操作

  • 對(duì)volatile變量V的寫(xiě)入,與所有其它線(xiàn)程后續(xù)對(duì)V的讀同步


    而要滿(mǎn)足這些條件volatile關(guān)鍵字就具有以下功能:

  • 禁止緩存,volatile變量的訪問(wèn)控制符會(huì)加個(gè)ACC_VOLATILE,《Java虛擬機(jī)規(guī)范》 中的對(duì)它的描述就是“cannot be cached”

  • 對(duì)volatile變量相關(guān)的指令不做重排序

上述就是小編為大家分享的Java內(nèi)存模型以及線(xiàn)程安全的可見(jiàn)性問(wèn)題是怎樣的了,如果剛好有類(lèi)似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


分享名稱(chēng):Java內(nèi)存模型以及線(xiàn)程安全的可見(jiàn)性問(wèn)題是怎樣的
本文路徑:http://weahome.cn/article/iheeos.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部