1. 程式人生 > >監聽器-java同步的基本思想

監聽器-java同步的基本思想

原文地址  作者: X Wang   譯者:龐俊濤

如果你在大學學習過作業系統,你可能還記得監聽器在作業系統中是很重要的概念。同樣監聽器在java同步機制中也有使用,本文通過類比的方法來解釋“監聽器”的基本思想。

什麼是監聽器?

監聽器可以看成是包含了一間特殊房間的建築,這間特殊的房間在同一個時間只能被一個客人(執行緒)擁有,通常這間房間包含了一些資料和程式碼。

Java-Monitor

如果一個客人想擁有這間特殊的房間,他不得不首先在走廊(進入集)中等待著,然後排程器根據一些排程演算法(eg:FIFO 先進先出)選擇一個。如果這個客人因為某些原因暫停懸掛著,則會被放到等待房間`,同時也被安排稍後重新進入這個特殊的房間,就像上面圖片所展示的那樣,在這個建築裡有個3個房間。

java-monitor-associate-with-object

簡而言之:一個監聽器就是一個監聽執行緒進入這間特殊房間的設施。它確保了只能有一個執行緒可以訪問這些受到保護的資料和程式碼。

在java中監聽器是如何實現的?

在java虛擬機器中,每個物件和類在邏輯上都和一個監聽器相關聯。為了實現監聽器的共同執行能力,鎖(有時候又叫互斥量)關聯著每個物件和類,在作業系統書上被稱之為“訊號量”,互斥量其實就是一個二態的訊號量。

如果一個執行緒拿到了相關資料的鎖,那麼其他執行緒不能再擁有這把鎖直到擁有這把鎖的執行緒釋放了這把鎖。當在多執行緒程式設計中,如果我們需要一直寫一個訊號量這種方式可能會不太方便,幸運的是我們沒必要這麼做,因為JVM(java虛擬機器)已經自動幫我們做了。

宣告一個監聽器區域,這意味著資料不能被超過一個執行緒訪問(譯者注:同時訪問的前提)。Java提供了同步的語句和同步的方法,一旦程式碼嵌入到同步關鍵字內,這就是一個監聽器區域。而鎖是由jvm在底層自動實現的。

在java同步程式碼中,哪部分才是監聽器?

我們知道每個物件/類都關聯著一個監聽器,我覺得這麼說好點,每個物件都擁有一個監聽器,因為每個物件都有它關鍵的區域和監聽執行緒佇列的能力。

為了使不同執行緒能相互合作,java提供了wait()和notify()方法來暫停一個執行緒和喚醒分別等待訪問這個物件的其他執行緒中的一個,另外還有3個其他版本:

wait(long timeout, int
nanos) wait(long timeout) notified by other threads or notified by timeout. notify(all)

這些方法只能在一個同步語句或者同步方法內呼叫,原因是因為如果一個方法不要求互斥,那麼就沒有必要線上程間監聽或者是合作,每個執行緒都可以自由訪問這個方法。

這裡是一些同步程式碼的例子。