中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

深入理解Java多線程與并發框(第③篇)——Java內存模型與原子性、可見性、有序性

發布時間:2020-08-15 01:17:58 來源:ITPUB博客 閱讀:241 作者:無敵天驕 欄目:軟件技術

深入理解Java多線程與并發框(第③篇)——Java內存模型與原子性、可見性、有序性

深入理解Java多線程與并發框(第③篇)——Java內存模型與原子性、可見性、有序性

一、Java內存模型

Java Memory Modle,簡稱 JMM,中文名稱 Java內存模型,它是一個抽象的概念,用來描述或者規范訪問內存變量的方式。因為各中計算機的操作系統和硬件不同,方式機制也可能不同,Java內存模型用于屏蔽(適配)各種差異,以此來達到訪問各個平臺的一致的效果。這也是Java夸平臺的重要原因之一。

主內存: Java內存規定了所有變量都存儲在主內存(Main Memory)中,各個線程又有自己的本地內存(工作內存),本地內存保存著主內存中部分變量。具體訪問方式如下:

深入理解Java多線程與并發框(第③篇)——Java內存模型與原子性、可見性、有序性

JMM工作方式

  • lock加鎖:為了保證訪問主內存變量的線程安全性,在訪問前一般會加鎖處理;
  • read讀:從主內存中讀取一個變量到工作內存;
  • load加載:把read讀到的變量加載到工作內存的變量副本中;
  • use使用:此時線程可以使用其工作內存中的變量了;
  • assign賦值:將處理后的變量賦值給工作內存中的變量;
  • store存儲:將工作內存中的變量存儲到主內存中,以新建new 一個新變量的方式存儲;
  • write寫:將store存在的新變量的引用賦值給被處理的變量;
  • unload解鎖:所有的工作做完,最后解鎖釋放資源。

二、Java內存模型的三大特性

1. 原子性(Atomicity)

這里的原子性如同數據庫事務中是原子性,一個或多個操作要么全執行成功要么全執行失敗(全不執行)。

int a = 1;
a++;
double b = 1.5;

Java內存模型只保證單一的操作具有原子性,比如上面的 int a = 1; 是一個單子的操作,所以具有原子性。而 a++ 操作在底層會分為三個操作:1)、讀取a的值給臨時變量;2)、臨時變量a的值加1操作;3)、將加操作后的值賦值給a。每個操作都是原子的,但Java內存模型在多線程下并不能保證多操作具有整體原子性,因為它也不知道這個整體內有多少操作,用戶想要達到多操作具有整體原子性,需要對響應的代碼塊做同步(synchronous)處理,比如使用 有鎖的synchronized 或 無鎖的CAS。

2. 可見性(Visibility)

這里的可見性是內存可見性。

深入理解Java多線程與并發框(第③篇)——Java內存模型與原子性、可見性、有序性

如上圖,線程1和線程2在未同步的情況下對共享內存(主內存)中的變量進行訪問,比如兩個線程的操作都是對變量a進行加1操作。假設線程1首先獲取主內存中變量a的值,隨后線程2又獲取了主內存變量a的值,此時它們工作內存中a的值都是1,它們各自將a的值加1操作,然后assign至工作內存,工作內存中變量a的值都是2,然后兩個線程又將值刷新到主內存,最后的結果是主內存中變量a的值是2。雖然整體對a的值加1操作做了兩次操作,但由于線程間的操作是互相隔離的,默認情況下無法感知內存變量的值在隨后的變化,也就無法訪問內存中最新的變量值,這就是內存可行性的問題。

如何解決內存可見性的問題?

  • 對進入臨界區的線程做同步處理(比如 synchronized),同一時刻僅有一個線程能夠訪問臨界區的資源;
  • 使用 volatile 關鍵字保證內存可見性,它能保證訪問臨界區資源的所有線程總能看到共享資源的最新值;
  • CAS無鎖化。

3. 有序性(Ordering)

線程內的所有操作都是有序的,既程序執行的順序按照代碼的先后順序執行。比如下面的示例:

int a = 1;
int b = 2;
int c = a + b;

線程內程序會先執行 int a = 1; ,然后執行 int b = 2; 最后執行int c = a + b;。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

乌拉特后旗| 云和县| 凤翔县| 龙南县| 凌海市| 保德县| 元阳县| 新密市| 黔西| 霍邱县| 宜君县| 芜湖县| 凭祥市| 天祝| 永顺县| 定日县| 宜兰市| 蓬安县| 云南省| 山丹县| 黄大仙区| 长海县| 南安市| 营口市| 双鸭山市| 宁波市| 宽城| 尼木县| 始兴县| 威海市| 瑞安市| 盐池县| 湖北省| 博客| 德江县| 响水县| 特克斯县| 渝中区| 泰兴市| 和静县| 翁牛特旗|