java虛擬機的一些運行時(shí)數據區會(huì )被所有線(xiàn)程共享,其他的數據是各個(gè)線(xiàn)程私有的。
因為堆和方法區是被所有線(xiàn)程共享的,java程序需要為兩種多線(xiàn)程訪(fǎng)問(wèn)數據進(jìn)行協(xié)調。
1)保存在堆中的實(shí)例變量
2)保存在方法區中的類(lèi)變量
程序不需要協(xié)調保存在java棧中的局部變量,因為java棧中的數據是屬于擁有該棧的線(xiàn)程私有的。
在java虛擬機中,每個(gè)對象和類(lèi)在邏輯上都是和一個(gè)監視器相關(guān)聯(lián)的。對于對象來(lái)說(shuō),相關(guān)聯(lián)的監視器保護對象的實(shí)例變量。對于類(lèi)來(lái)說(shuō),監視器保護類(lèi)的類(lèi)變量。如果一個(gè)對象沒(méi)有實(shí)例變量,或者一個(gè)類(lèi)沒(méi)有變量,相關(guān)聯(lián)的監視器就什么也不監視。
為了實(shí)現監視器的排他性監視能力,java虛擬機為每一個(gè)對象和類(lèi)都關(guān)聯(lián)一個(gè)鎖。代表任何時(shí)候只允許一個(gè)線(xiàn)程擁有的特權。線(xiàn)程訪(fǎng)問(wèn)實(shí)例變量或者類(lèi)變量不需鎖。但是如果線(xiàn)程獲取了鎖,那么在它釋放這個(gè)鎖之前,就沒(méi)有其他線(xiàn)程可以獲取同樣數據的鎖了。(鎖住一個(gè)對象就是獲取對象相關(guān)聯(lián)的監視器)
類(lèi)鎖實(shí)際上用對象鎖來(lái)實(shí)現。當虛擬機裝載一個(gè)class文件的時(shí)候,它就會(huì )創(chuàng )建一個(gè)java。lang。class類(lèi)的實(shí)例。當鎖住一個(gè)對象的時(shí)候,實(shí)際上鎖住的是那個(gè)類(lèi)的class對象。
一個(gè)線(xiàn)程可以多次對同一個(gè)對象上鎖。對于每一個(gè)對象,java虛擬機維護一個(gè)加鎖計數器,線(xiàn)程每獲得一次該對象,計數器就加1,每釋放一次,計數器就減1,當計數器值為0時(shí),鎖就被完全釋放了。
java編程人員不需要自己動(dòng)手加鎖,對象鎖是java虛擬機內部使用的。在java程序中,只需要使用同步語(yǔ)句或者同步方法就可以標志一個(gè)監視區域。當每次進(jìn)入一個(gè)監視區域時(shí),java虛擬機都會(huì )自動(dòng)鎖上對象或者類(lèi)。
聯(lián)系客服