<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 13 問題的根源—Java內存模型簡介 > 世界上最寬闊的是海洋,比海洋更寬闊的是天空,比天空更寬闊的是人的胸懷。 > ——雨果 JAVA內存模型即JMM(Java Memory Model),有些人會和Java內存結構混淆。雖然兩者名字很接近,但描述的為不同內容。Java內存結構描述的是JVM對內存的邏輯劃分,我們在學習垃圾回收和JVM優化的時候會關心JVM內存結構。而本節所講的JMM,實際上是一種規范。它描述了Java程序的運行行為,包括多線程操作對共享內存讀取時,所能讀取到的值應該遵守的規則。 ## 1\. JMM的必要性 隨著CPU的不斷發展,CPU的性能越來越強大,但受迫于頻率提升的困難,現代CPU架構開始向多核發展。而作為軟件開發人員為了充分使用CPU的性能,越來越多的開發者會選擇多線程程序開發。CPU在計算時會做一些優化,這些優化對于單線程程序來說是沒有問題的,但對多線程程序則不是那么的友好。 計算機在運行時,絕大多數時間都會把對象信息保存在內存中。但是在此期間,編譯器、處理器或者緩存都可能會把變量從分配的內存中取出處理再放回。比如我們在while循環中判斷flag是否為true來執行一段特定的邏輯,那么編譯器為了優化可能會選擇把flag值取到緩存中。此時主存中的flag值可能會被其它線程所改變,但是此線程是無法感知的。直到某個特定的時機觸發此線程從主存中刷新flag值。所有這些優化都是為了程序有更好的性能。在單線程的程序中,這種優化對于用戶來講是毫無感知的,不過多線程的程序中,這種優化有些時候會造成難以預料的結果。 JMM允許編譯器和緩存保持對數據操作順序優化的自由度。除非程序使用Synchronized或者volatile顯式的告訴處理器需要確保可見性。這意味著如果你沒有進行同步,那么多線程程序對于數據的操作,將會呈現不同的順序。也就是前面一節講的有序性,我們基于代碼順序對數據賦值順序的推論,在多線程程序中可能會不成立。 在JMM之前,C和C++并沒有顯式的內存模型。C語言的內存模型繼承自執行程序的處理器。這意味著并發的C語言程序,在不同的處理器機構上可能會呈現不一樣的結果。但JMM使得Java程序能夠在任何JVM上表現出一樣的行為。當然,現在C和C++也有了內存模型。 ![圖片描述](https://img.mukewang.com/5d9167b0000103c707700460.jpg) ## 2\. JMM簡介 JMM為程序中的所有操作定義了一定的規則,叫做Happens-Before。無論兩個操作是否在同一個線程,如果要想保證操作A能看到操作B的結果,那么A、B之間一定要滿足Happens-Before關系。如果兩者間不滿足Hapen-Before關系,JVM可以對其任意重排序。 當多個線程同時讀寫同一個變量,但這些操作間又沒有滿足Happens-Before關系,那么這些線程對此變量存在數據競爭,整個程序將會陷入混亂之中。假如我們在操作共享變量時采用了同步,那么無論有多少線程,對此變量的操作都會呈現出串行一致性。從而使得多線程的操作順序遵守JMM約定。 ## 3\. Happens-Before規則 Happens-Before在多線程領域具有重大意義,它可以指導你如何開發多線程的程序,而不至于陷入混亂之中。你所開發的多線程程序,如果想對共享變量的操作符合你設想的順序,那么需要依照Happens-Before原則來開發。happens-before并不是指操作A先于操作B發生,而是指操作A的結果在什么情況下可以被后面操作B所獲取。下面我們就來看一下Happens-before原則。 1. 程序順序規則。如果程序中A操作在B操作之前,那么線程中A操作將在B操作前執行。 2. 上鎖原則。不同線程對同一個鎖的lock操作一定在unclock前。 3. volatile變量原則。對于volatile變量的寫操作會早于對其的讀操作。 4. 線程啟動原則。A線程中調用threadB.start()方法,那么threadB.start()方法會早于B線程中中的任何動作執行。 5. 傳遞規則。如果A早于B執行,B早于C執行,那么A一定早于C執行。 6. 線程中斷規則:線程interrupt()方法的一定早于檢測到線程的中斷信號。 7. 線程終結規則:如果線程A終結了,并且導致另外一個線程B中的ThreadA.join()方法取得返回,那么線程A中所有的操作都早于線程B在ThreadA.join()之后的動作發生。 8. 對象終結規則:一個對象初始化操作肯定先于它的finalize()方法。 我們只有充分理解了happens-before原則,才能在編寫多線程程序的時候,盡量避免數據的不一致性,讓多線程程序在必要的時候按照我們設計的次序執行。 ## 4\. 總結 JMM是程序執行順序的指導原則,通過JMM的約束,我們能夠設計出符合我們要求的多線程程序。其實不止多線程,單線程程序一樣受到JMM的約束。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看