1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      深入理解Java內(nèi)存模型詳解

      原子性
      原子性即一個操作或一系列是不可中斷的。即使是在多個線程的情況下,操作一旦開始,就不會被其他線程干擾。

      創(chuàng)新互聯(lián)服務(wù)項目包括達(dá)川網(wǎng)站建設(shè)、達(dá)川網(wǎng)站制作、達(dá)川網(wǎng)頁制作以及達(dá)川網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,達(dá)川網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到達(dá)川省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

      比如,對于一個靜態(tài)變量int x兩條線程同時對其賦值,線程A賦值為1,而線程B賦值為2,不管線程如何運(yùn)行,最終x的值要么是1,要么是2,線程A和線程B間的操作是沒有干擾的,這就是原子性操作,不可被中斷的。

      Java內(nèi)存模型對以下操作保證其原子性:read,load,assign,use,store,write。我們可以大致認(rèn)為基本數(shù)據(jù)類型的訪問讀寫是具備原子性的(前面也提到了long和double類型的“半個變量”情況,不過幾乎不會發(fā)生)。

      從Java內(nèi)存模型底層來看有上面的原子性操作,但針對用戶來說,也就是我們編寫Java的程序,如果需要更大范圍的原子性保障,就需要同步關(guān)鍵字——synchronized來保障了。也就是說synchronized中的操作也具有原子性。

      可見性
      可見性是指當(dāng)一個線程修改了共享變量的值,其他線程能夠立即得知這個修改。

      Java內(nèi)存模型是通過變量修改后將新值同步回主內(nèi)存,在變量讀取前從主內(nèi)存刷新變量值,將主內(nèi)存作為傳遞媒介。可回顧一下上篇文章的圖。

      無論普通變量還是volatile變量都是如此,只不過volatile變量保證新值能夠立馬同步到主內(nèi)存,使用時也立即從主內(nèi)存刷新,保證了多線程操作時變量的可見性。而普通變量不能夠保證。

      除了volatile,synchronized和final也能夠?qū)崿F(xiàn)可見性。

      synchronized實(shí)現(xiàn)的可見性是通過“對一個變量執(zhí)行unlock操作之前,必須先把此變量同步回主內(nèi)存中”來保證的。

      主要有兩個原則:線程解鎖前,必須把共享變量的最新值刷新到主內(nèi)存中;線程加鎖時,將清空工作內(nèi)存中共享變量的值,從而使用共享變量時需要從主內(nèi)存中重新讀取最新的值。

      final的可見性是指:被final修飾的字段在構(gòu)造器中一旦初始化完成,并且構(gòu)造器沒有把“this”的引用傳遞出去,那在其他線程中就能看見final的值。

      有序性
      在Java內(nèi)存模型中有序性可歸納為這樣一句話:如果在本線程內(nèi)觀察,所有操作都是有序的,如果在一個線程中觀察另一個線程,所有操作都是無序的。

      有序性是指對于單線程的執(zhí)行代碼,執(zhí)行是按順序依次進(jìn)行的。但在多線程環(huán)境中,則可能出現(xiàn)亂序現(xiàn)象,因?yàn)樵诰幾g過程會出現(xiàn)“指令重排”,重排后的指令與原指令的順序未必一致。

      因此,上面歸納的前半句指的是線程內(nèi)保證串行語義執(zhí)行,后半句則指指“令重排現(xiàn)”象和“工作內(nèi)存與主內(nèi)存同步延遲”現(xiàn)象。

      同樣,Java語言提供了volatile和synchronized兩個關(guān)鍵字來保證線程之間操作的有序性。

      指令重排
      計算機(jī)執(zhí)行指令經(jīng)過編譯之后形成指令序列。一般情況,指令序列是會輸出確定的結(jié)果,且每一次的執(zhí)行都有確定的結(jié)果。

      CPU和編譯器為了提升程序執(zhí)行的效率,會按照一定的規(guī)則允許進(jìn)行指令優(yōu)化。但代碼邏輯之間是存在一定的先后順序,并發(fā)執(zhí)行時按照不同的執(zhí)行邏輯會得到不同的結(jié)果。

      編譯器優(yōu)化重排序:編譯器在不改變單線程程序語義的前提下,重新安排語句執(zhí)行順序。

      指令級并行重排序:處理器采用了指令級并行技術(shù)來將多條指令重疊執(zhí)行。如果不存在數(shù)據(jù)依賴性,處理器可以改變語句對應(yīng)及其的執(zhí)行順序。

      內(nèi)存系統(tǒng)的重排序:處理器使用緩存和讀/寫緩沖區(qū),使得加載和存儲操作看上去可能是亂序執(zhí)行。

      舉個例來說明一下多線程中可能出現(xiàn)的重排現(xiàn)象:

      class ReOrderDemo { ? ?int a = 0; ? ?boolean flag = false; ? ?public void write() { ? ? ? ?a = 1; ? ? ? ? ? ? ? ? ? //1 ? ? ? ?flag = true; ? ? ? ? ? ? //2 ? ?} ? ? ? ?public void read() { ? ? ? ?if (flag) { ? ? ? ? ? ? ? ?//3 ? ? ? ? ? ?int i = ?a * a; ? ? ? ?//4 ? ? ? ? ? ?…… ? ? ? ?} ? ?} }

      在上面的代碼中,單線程執(zhí)行時,read方法能夠獲得flag的值進(jìn)行判斷,獲得預(yù)期結(jié)果。但在多線程的情況下就可能出現(xiàn)不同的結(jié)果。

      比如,當(dāng)線程A進(jìn)行write操作時,由于指令重排,write方法中的代碼執(zhí)行順序可能會變成下面這樣:

      flag = true; ? ? ? ? ? ? //2a = 1; ? ? ? ? ? ? ? ? ? //1

      也就是說可能會先對flag賦值,然后再對a賦值。這在單線程中并不影響最終輸出的結(jié)果。

      但如果與此同時,B線程在調(diào)用read方法,那么就有可能出現(xiàn)flag為true但a還是0,這時進(jìn)入第4步操作的結(jié)果就為0,而不是預(yù)期的1了。

      請記住,指令重排只會保證單線程中串行語義執(zhí)行的一致性,不會關(guān)心多線程間語義的一致性。這也是為什么在寫單例模式時需要考慮添加volatile關(guān)鍵詞來修飾,就是為了防止指令重排導(dǎo)致的問題。

      JMM提供的解決方案
      在了解了原子性、可見性以及有序性問題后,看看JMM是提供了什么機(jī)制來保證這些特性的。

      原子性問題,除了JVM自身提供的對基本數(shù)據(jù)類型讀寫操作的原子性外,對于方法級別或者代碼塊級別的原子性操作,可以使用synchronized關(guān)鍵字或者重入鎖(ReentrantLock)保證程序執(zhí)行的原子性。

      而工作內(nèi)存與主內(nèi)存同步延遲現(xiàn)象導(dǎo)致的可見性問題,可以使用synchronized關(guān)鍵字或者volatile關(guān)鍵字解決。它們都可以使一個線程修改后的變量立即對其他線程可見。

      對于指令重排導(dǎo)致的可見性問題和有序性問題,則可以利用volatile關(guān)鍵字解決。volatile的另一個作用就是禁止重排序優(yōu)化。

      除了靠sychronized和volatile關(guān)鍵字之外,JMM內(nèi)部還定義一套happens-before(先行發(fā)生)原則來保證多線程環(huán)境下兩個操作間的原子性、可見性以及有序性。


      本文名稱:深入理解Java內(nèi)存模型詳解
      網(wǎng)站地址:http://ef60e0e.cn/article/gigohh.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        凤山市| 苏州市| 永年县| 施秉县| 灵丘县| 晋城| 西盟| 根河市| 炉霍县| 尉犁县| 五峰| 章丘市| 彭水| 牙克石市| 尚志市| 阿拉善盟| 赤壁市| 定陶县| 荆州市| 佛坪县| 墨玉县| 西乌| 黎川县| 乌鲁木齐县| 六盘水市| 崇义县| 渝中区| 应城市| 洪雅县| 佛山市| 嘉义县| 曲周县| 湖北省| 南丰县| 昭平县| 舟山市| 德庆县| 富源县| 黑水县| 武功县| 柯坪县|