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

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

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

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

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

一、Java內(nèi)存模型

Java Memory Modle,簡稱 JMM,中文名稱 Java內(nèi)存模型,它是一個(gè)抽象的概念,用來描述或者規(guī)范訪問內(nèi)存變量的方式。因?yàn)楦髦杏?jì)算機(jī)的操作系統(tǒng)和硬件不同,方式機(jī)制也可能不同,Java內(nèi)存模型用于屏蔽(適配)各種差異,以此來達(dá)到訪問各個(gè)平臺(tái)的一致的效果。這也是Java夸平臺(tái)的重要原因之一。

成都創(chuàng)新互聯(lián)公司長期為超過千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為龍泉企業(yè)提供專業(yè)的成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì),龍泉網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

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

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

JMM工作方式

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

二、Java內(nèi)存模型的三大特性

1. 原子性(Atomicity)

這里的原子性如同數(shù)據(jù)庫事務(wù)中是原子性,一個(gè)或多個(gè)操作要么全執(zhí)行成功要么全執(zhí)行失?。ㄈ粓?zhí)行)。

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

Java內(nèi)存模型只保證單一的操作具有原子性,比如上面的 int a = 1; 是一個(gè)單子的操作,所以具有原子性。而 a++ 操作在底層會(huì)分為三個(gè)操作:1)、讀取a的值給臨時(shí)變量;2)、臨時(shí)變量a的值加1操作;3)、將加操作后的值賦值給a。每個(gè)操作都是原子的,但Java內(nèi)存模型在多線程下并不能保證多操作具有整體原子性,因?yàn)樗膊恢肋@個(gè)整體內(nèi)有多少操作,用戶想要達(dá)到多操作具有整體原子性,需要對響應(yīng)的代碼塊做同步(synchronous)處理,比如使用 有鎖的synchronized 或 無鎖的CAS。

2. 可見性(Visibility)

這里的可見性是內(nèi)存可見性。

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

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

如何解決內(nèi)存可見性的問題?

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

3. 有序性(Ordering)

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

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

線程內(nèi)程序會(huì)先執(zhí)行 int a = 1; ,然后執(zhí)行 int b = 2; 最后執(zhí)行int c = a + b;。


分享名稱:深入理解Java多線程與并發(fā)框(第③篇)——Java內(nèi)存模型與原子性、可見性、有序性
分享地址:http://weahome.cn/article/ihgoss.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部