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)存中部分變量。具體訪問方式如下:
JMM工作方式
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)存可見性。
如上圖,線程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)存可見性的問題?
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;。