本篇內(nèi)容介紹了“Java內(nèi)存模型的規(guī)定是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的迭部網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
首先要明確內(nèi)存模型指什么。書中的定義是:在特定的操作協(xié)議下,對(duì)特定內(nèi)存和高速緩存進(jìn)行讀寫訪問的過程抽象。 |
可以知道,內(nèi)存模型就是來規(guī)定如何對(duì)內(nèi)存/緩存進(jìn)行讀寫操作的。所以Java內(nèi)存模型,就是用來定義程序?qū)ava內(nèi)存的的訪問規(guī)則。進(jìn)一步說, Java內(nèi)存模型就是定義程序中變量(靜態(tài)變量、數(shù)組對(duì)象元素等,不包括局部變量、方法參數(shù))的訪問規(guī)則。
Java內(nèi)存模型的規(guī)定:
所有變量存儲(chǔ)在主內(nèi)存中;
每個(gè)線程都有自己的工作內(nèi)存,且對(duì)變量的操作都是在工作內(nèi)存中進(jìn)行;
不同線程之間無法直接訪問彼此工作內(nèi)存中的變量,要想訪問只能通過主內(nèi)存來傳遞。
Java的線程、工作內(nèi)存、主內(nèi)存關(guān)系如下圖所示:
具體變量從主內(nèi)存到工作內(nèi)存,以及從工作內(nèi)存轉(zhuǎn)回主內(nèi)存的實(shí)現(xiàn)細(xì)節(jié),由下面八個(gè)原子性的操作完成:
lock:作用于主內(nèi)存變量,將該變量標(biāo)識(shí)為一個(gè)線程獨(dú)占的狀態(tài)
unlock:作用于主內(nèi)存變量,將獨(dú)占狀態(tài)釋放
read:作用于主內(nèi)存變量,將值拷貝到工作內(nèi)存中
load:作用于工作內(nèi)存中的變量,將值放到工作內(nèi)存中的變量副本中
use:作用于工作內(nèi)存中的變量,將值傳給執(zhí)行引擎
asign:作用于工作內(nèi)存中的變量,將執(zhí)行引擎中的值賦給工作內(nèi)存中的變量
store:作用于工作內(nèi)存中的變量,將值傳給主內(nèi)存
write:作用于主內(nèi)存中的變量,將工作內(nèi)存中返回的值放到主內(nèi)存變量中
同時(shí)還對(duì)上述八個(gè)操作進(jìn)行了一些細(xì)節(jié)的要求,比如read/load、store/write必須成對(duì)出現(xiàn),未執(zhí)行過lock的變量不能執(zhí)行unlock操作等。
劃重點(diǎn),此處面試常遇到的問題就是對(duì)于volatile關(guān)鍵字的解讀。
volatile關(guān)鍵字
此關(guān)鍵字修飾的變量具有兩種效果:1、保證線程間的可見性;2、阻止指令重排序
對(duì)于1的實(shí)現(xiàn),它保證load與use必須相鄰調(diào)用,即要use這個(gè)變量,必定先執(zhí)行read/load,這樣每次都能獲取到最新的變量值;它又保證asign與store必須相鄰調(diào)用,即在工作內(nèi)存中將該變量改了之后,必定會(huì)先同步到主內(nèi)存中。這樣,volatile關(guān)鍵字實(shí)現(xiàn)了可見性。至于阻止指令重排序,還是移步《深入理解Java虛擬機(jī)》一書吧,貧道水平有限,就不在這里說了。
從另一個(gè)角度來分析,Java內(nèi)存模型是圍繞著在并發(fā)過程中如何處理原子性、可見性、有序性來建立的。
原子性:八個(gè)原子性操作,以及synchronized(lock/unlock未直接開放給用戶,synchronized通過monitorenter跟monitorexit指令調(diào)用的lock/unlock操作)
可見性:volatile、synchronized、final這三個(gè)關(guān)鍵字均通過不同方式實(shí)現(xiàn)了可見性
有序性:volatile、synchronized 這兩個(gè)關(guān)鍵字保證有序性,同時(shí)還有先行發(fā)生(happens-before)原則來保證隱含的默認(rèn)有序性
下面說說happens-before先行發(fā)生原則,先行發(fā)生原則用通俗語言表述就是:如果操作A在操作B之前發(fā)生,那么A產(chǎn)生的影響B(tài)同樣能觀測到。那么問題來了,先行發(fā)生原則都有哪些呢?同樣有八條,如下:
程序次序規(guī)則:同一個(gè)線程中按照代碼的順序依次執(zhí)行
管程鎖定規(guī)則:對(duì)于同一個(gè)鎖,unlock先行發(fā)生于后面的lock,即unlock了才會(huì)lock
volatile變量規(guī)則:對(duì)一個(gè)volatile變量的寫操作先行發(fā)生于后面對(duì)該變量的讀操作,即寫完了才會(huì)讀
線程啟動(dòng)規(guī)則:一個(gè)線程的start()方法先行發(fā)生于此線程的任何一個(gè)動(dòng)作
線程終止規(guī)則:一個(gè)線程的所有動(dòng)作先行發(fā)生于該線程的終止檢測
線程中斷規(guī)則:對(duì)一個(gè)線程interrupt()方法的調(diào)用先行發(fā)生于線程的中斷檢測Thread.interrpted()
對(duì)象終結(jié)規(guī)則:對(duì)象的初始化完成先行發(fā)生于finalize()方法
傳遞性:顧名思義,A先行發(fā)生于B,B先行發(fā)生于C,則A一定先行發(fā)生于C
“Java內(nèi)存模型的規(guī)定是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!