多線程編程(一) Java內存模型(Java Memory Model)


一、概述

  Java內存模型是Java語言在多線程並發情況下對於共享變量讀寫(實際是共享變量對應的內存操作)的規范,主要是為了解決多線程可見性、原子性的問題,解決共享變量的多線程操作沖突問題。】

       

  JMM描述了Java程序中各種變量(線程共享變量)的訪問規則,以及在JVM中將變量存儲到內存中讀取出變量這樣的底層細節。所有的變量都存儲在主內存中,每個線程都有自己獨立的工作內存,里面保存該線程使用到的變量的副本(主內存中變量的一份拷貝)

        JMM的兩條規定
  1、線程對共享變量的所有操作都必須在自己的工作內存中進行,不能直接從主內存中讀寫;
  2、不同的線程之間無法直接訪問其他線程工作內存中的變量,線程變量值的傳遞需要通過主內存來完成。

 

 

    (:Java內存模型(JMM) 和 JVM 內存模型區別 :https://www.cnblogs.com/Jomini/p/13176653.html

 

二、並發編程問題

  多線程並發編程會涉及到以下的問題:

  1)原子性:指在一個操作中就是cpu不可以在中途暫停然后再調度,既不被中斷操作,要不執行完成,要不就不執行。

  2)可見性:指當多個線程訪問同一個變量時,一個線程修改了這個變量的值,其他線程能夠立即看得到修改的值。

  3)有序性:程序執行的順序按照代碼的先后順序執行,多線程中為了提高性能,編譯器和處理器的常常會對指令做重排(編譯器優化重排、指令並行重排、內存系統重排)。

 

三、解決並發編程

         1)原子性:Java提供了兩個高級字節碼指令monitorenter和monitorexit,對應的是關鍵字synchronized,使用該關鍵字保證方法和代碼塊內的操作的原子性。

         2)可見性:Java中的volatile關鍵字提供了一個功能,那就是被其修飾的變量在被修改后可以立即同步到主內存,被其修飾的變量在每次是用之前都從主內存刷新。因此,可以使用volatile來保證多線程操作時變量的可見性。

除了volatile,Java中的synchronized和final兩個關鍵字也可以實現可見性,只不過實現方式不同

  3)有序性:用volatile關鍵字禁止指令重排,用synchronized關鍵字加鎖。

 

四、指令重新排序

       CPU優化性能

     

 

 

 

 

 

 

 

 

參考:

https://blog.csdn.net/qq_41297896/article/details/89949632

https://blog.csdn.net/zengxiantao1994/article/details/89303290


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM