溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Java管程的概念和實(shí)現(xiàn)原理

發(fā)布時(shí)間:2021-06-18 16:11:39 來(lái)源:億速云 閱讀:705 作者:chen 欄目:編程語(yǔ)言

本篇內(nèi)容主要講解“Java管程的概念和實(shí)現(xiàn)原理”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Java管程的概念和實(shí)現(xiàn)原理”吧!

管程的概念

在操作系統(tǒng)的概念里,monitor(管程)是為了解決使用信號(hào)量同步容易出錯(cuò)的問(wèn)題,而提出的一種高級(jí)同步原語(yǔ)。monitor是編程語(yǔ)言的組成部分,進(jìn)入monitor時(shí)的互斥由編譯器來(lái)負(fù)責(zé),寫(xiě)monitor的人無(wú)需關(guān)心編譯器是如何實(shí)現(xiàn)互斥的,只需要將所有臨界區(qū)轉(zhuǎn)換成monitor即可。盡管管程提供了一種實(shí)現(xiàn)互斥的簡(jiǎn)單方式,但是還不夠,還需要一種辦法使得進(jìn)程/線(xiàn)程在無(wú)法繼續(xù)執(zhí)行時(shí)被阻塞,解決的方法是引入條件變量以及兩個(gè)相關(guān)的操作:wait和signal。Java是真正支持管程的編程語(yǔ)言之一。

Java中的monitor支持兩種類(lèi)型的線(xiàn)程同步: 互斥鎖同步和協(xié)作同步。在Java虛擬機(jī)中通過(guò)object locks支持的互斥鎖,允許多個(gè)線(xiàn)程獨(dú)立地工作在共享數(shù)據(jù)上,而不會(huì)互相干擾(在使用上即synchronized關(guān)鍵字,這里提到的是虛擬機(jī)層原理)。Java虛擬機(jī)通過(guò)Object類(lèi)的 wait 和 notify 方法支持協(xié)作,使線(xiàn)程能夠朝著共同的目標(biāo)協(xié)同工作。

互斥鎖同步

一個(gè)monitor就像一棟樓里面的一個(gè)特殊房間,在同一時(shí)間內(nèi)只能被一個(gè)線(xiàn)程所占有,這個(gè)房間通常包含一些數(shù)據(jù),從線(xiàn)程進(jìn)入這個(gè)房間到離開(kāi)這個(gè)房間,它可以訪問(wèn)房間里的任何數(shù)據(jù)。

  • 進(jìn)入這棟樓,稱(chēng)為entering the monitor。

  • 進(jìn)入這個(gè)特殊房間,稱(chēng)為acquiring the monitor。

  • 占有這個(gè)特殊房間,稱(chēng)為owning the monitor。

  • 離開(kāi)這個(gè)特殊房間,稱(chēng)為releasing the monitor。

  • 離開(kāi)這棟樓,稱(chēng)為exiting the monitor。

除了與數(shù)據(jù)關(guān)聯(lián)之外,一個(gè)monitor還被關(guān)聯(lián)了很多的代碼,稱(chēng)為monitor regions。monitor regions包含一段原子的,不可分割的執(zhí)行的代碼。

當(dāng)線(xiàn)程到達(dá)monitor regions的開(kāi)始位置時(shí),它將被放置到所關(guān)聯(lián)monitor的一個(gè) entry set中。 entry set類(lèi)似于monitor大樓的前門(mén)廊。如果在entry set中沒(méi)有其他線(xiàn)程在等待,且當(dāng)前沒(méi)有其他線(xiàn)程擁有monitor,則線(xiàn)程獲取monitor并繼續(xù)執(zhí)行monitor regions內(nèi)的代碼,執(zhí)行完成后,它退出并釋放monitor。

如果一個(gè)線(xiàn)程到達(dá)monitor regions的開(kāi)始位置時(shí),該monitor已經(jīng)被另一個(gè)線(xiàn)程所擁有,那么新到達(dá)的線(xiàn)程必須在 entry set中等待,只有當(dāng)擁有者退出monitor后,新到達(dá)的線(xiàn)程必須與同樣在entry set中等待的其他線(xiàn)程競(jìng)爭(zhēng),只有一個(gè)線(xiàn)程可以勝出并獲得monitor。

以上講述的是互斥鎖同步?;コ怄i同步是指由多個(gè)線(xiàn)程互斥地執(zhí)行monitor regions ,在任何時(shí)候,只有一個(gè)線(xiàn)程可以執(zhí)行特定monitor的monitor regions。一般來(lái)說(shuō),只有當(dāng)多個(gè)線(xiàn)程共享數(shù)據(jù)或其他資源時(shí),互斥鎖才是重要的。如果兩個(gè)線(xiàn)程不使用任何公共數(shù)據(jù)或資源,它們通常不會(huì)互相干擾,也不需要以互斥的方式執(zhí)行。

協(xié)作同步

當(dāng)一個(gè)線(xiàn)程需要某些數(shù)據(jù)處于特定狀態(tài),而另一個(gè)線(xiàn)程負(fù)責(zé)將數(shù)據(jù)轉(zhuǎn)換到該狀態(tài)時(shí),協(xié)作非常重要。例如,一個(gè)“寫(xiě)線(xiàn)程”負(fù)責(zé)填充的緩沖區(qū),一個(gè)“讀線(xiàn)程”從緩沖區(qū)取走數(shù)據(jù)。如果讀線(xiàn)程發(fā)現(xiàn)緩沖區(qū)為空,則必須等待寫(xiě)線(xiàn)程填充數(shù)據(jù)。如果寫(xiě)線(xiàn)程發(fā)現(xiàn)緩沖區(qū)滿(mǎn)了,則必須等待讀線(xiàn)程取走數(shù)據(jù)。

Java 虛擬機(jī)使用的monitor的形式稱(chēng)為"Wait and Notify" monitor,也可以稱(chēng)為"Signal and Continue" monitor,在這種monitor形式中,當(dāng)前擁有monitor的線(xiàn)程可以通過(guò)執(zhí)行 wait 命令暫停(suspended)自己,它釋放monitor并進(jìn)入一個(gè)wait set。線(xiàn)程將在wait set中保持暫停狀態(tài),直到另一個(gè)線(xiàn)程在monitor內(nèi)執(zhí)行notify命令后。當(dāng)一個(gè)線(xiàn)程執(zhí)行一個(gè) notify 時(shí),它繼續(xù)擁有monitor,直到它通過(guò)執(zhí)行一個(gè)wait命令,或者執(zhí)行完成monitor regions內(nèi)的代碼來(lái)釋放monitor。通知線(xiàn)程釋放monitor之后,等待線(xiàn)程將會(huì)復(fù)活(resurrected)并可以重新獲取monitor。

Java管程的概念和實(shí)現(xiàn)原理

圖中包含3個(gè)區(qū)域,中心區(qū)域包含一個(gè)活躍的線(xiàn)程(正在執(zhí)行的),該線(xiàn)程擁有monitor,可以執(zhí)行monitor regions內(nèi)的代碼,稱(chēng)之為monitor's owner,左邊是一個(gè) entry set,右邊是一個(gè)wait set。圖中有5扇門(mén),線(xiàn)程必須通過(guò)這些門(mén)與monitor交互。

當(dāng)一個(gè)線(xiàn)程執(zhí)行到monitor regions開(kāi)始的地方時(shí),它通過(guò)最左邊的1號(hào)門(mén)進(jìn)入 entry set,如果當(dāng)前沒(méi)有線(xiàn)程擁有monitor并且entry set中只有這一個(gè)線(xiàn)程,該線(xiàn)程會(huì)立即通過(guò)2號(hào)門(mén)成為monitor's owner,該線(xiàn)程可以繼續(xù)執(zhí)行monitor regions內(nèi)的代碼。如果當(dāng)前有其他線(xiàn)程擁有monitor,該線(xiàn)程必須在entry set中等待,這個(gè)區(qū)域中可能有很多個(gè)其他的線(xiàn)程在等待。

圖中 entry set中有3個(gè)掛起的線(xiàn)程,wait set中有4個(gè),只有當(dāng)monitor's owner釋放了monitor后,這些線(xiàn)程才有機(jī)會(huì)得到執(zhí)行。monitor's owner釋放monitor有2種方式:

  1. 執(zhí)行完成區(qū)域內(nèi)的代碼,通過(guò)5號(hào)門(mén)退出。

  2. 執(zhí)行wait命令,進(jìn)入wait set。

如果monitor's owner在釋放monitor之前沒(méi)有執(zhí)行notify命令,那么只有entry set中的線(xiàn)程會(huì)通過(guò)競(jìng)爭(zhēng)來(lái)獲得monitor。如果執(zhí)行了notify,那么entry set中的線(xiàn)程將不得不與wait set中線(xiàn)程競(jìng)爭(zhēng)。如果一個(gè)線(xiàn)程從entry set中競(jìng)爭(zhēng)獲勝,它通過(guò)2號(hào)門(mén),成為monitor的新主人。如果wait set中的一個(gè)線(xiàn)程競(jìng)爭(zhēng)獲勝,它通過(guò)4號(hào)門(mén)重新獲得monitor。注意,3號(hào)門(mén)和4號(hào)門(mén)是線(xiàn)程進(jìn)入或退出wait set的唯一方式,線(xiàn)程只有在當(dāng)前擁有monitor的情況下才能執(zhí)行 wait 命令,而且它不能自動(dòng)的離開(kāi)wait set并再次成為monitor's owner。

在Java虛擬機(jī)中,線(xiàn)程可以選擇在執(zhí)行wait命令時(shí)指定一個(gè)timeout。如果一個(gè)線(xiàn)程指定了timeout,如果在timeout到期之前沒(méi)有其他線(xiàn)程執(zhí)行通知,那么等待的線(xiàn)程會(huì)收到來(lái)自虛擬機(jī)的自動(dòng)通知。timeout過(guò)期后,即使沒(méi)有其他線(xiàn)程執(zhí)行顯式通知,等待線(xiàn)程也會(huì)恢復(fù)。Java虛擬機(jī)提供了兩種通知命令: “ notify”和“ notify all”。notify 命令可以從wait set中任意選擇一個(gè)線(xiàn)程,并將其標(biāo)記為恢復(fù)。notify all命令標(biāo)記當(dāng)前處于wait set中的所有線(xiàn)程恢復(fù)。

Java中Object類(lèi)聲明了5個(gè)方法(wait和notify),使程序員能夠使用Java虛擬機(jī)對(duì)同步協(xié)調(diào)方面的支持。這些方法被聲明為 public 和 final,因此它們被所有類(lèi)繼承,只能從同步的方法或語(yǔ)句中調(diào)用它們。換句話(huà)說(shuō),在調(diào)用這些方法中的任何一個(gè)之前,必須已經(jīng)獲取與對(duì)象關(guān)聯(lián)的鎖。

到此,相信大家對(duì)“Java管程的概念和實(shí)現(xiàn)原理”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI