當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > Java中的線程同步
在我們的操作系統(tǒng)上運(yùn)行著很多的計(jì)算機(jī)程序,每一個(gè)計(jì)算機(jī)程序可能都包含一個(gè)或多個(gè)獨(dú)立的線程,而這些線程若訪問我們系統(tǒng)上的共享資源時(shí),比如說:內(nèi)存資源、文件資源、數(shù)據(jù)庫資源等。可能會(huì)使得各線程之間訪問資源時(shí)產(chǎn)生沖突。那我們?nèi)绾蝸斫鉀Q這種問題呢?Java中存在這么幾種處理方式:同步代碼塊、同步方法、同步鎖等。
一、同步代碼塊
同步代碼塊格式:synchronized(key){
//存放同步代碼塊;
}
如何來理解同步代碼塊呢?打個(gè)比方:一個(gè)object就像一個(gè)大房子,大門永遠(yuǎn)打開。房子里有很多房間(也就是方法)。這些房間有上鎖的(synchronized方法),和不上鎖之分(普通方法)。房門口放著一把鑰匙(key),這把鑰匙可以打開所有上鎖的房間。另外我把所有想調(diào)用該對象方法的線程比喻成想進(jìn)入這房子某個(gè)房間的人。所有的東西就這么多了,下面我們看看這些東西之間如何作用的。
一個(gè)人想進(jìn)入某間上了鎖的房間,他來到房子門口,看見鑰匙在那兒(說明暫時(shí)還沒有其他人 要使用上鎖的房間)。于是他走上去拿到了鑰匙,并且按照自己的計(jì)劃使用那些房間。注意一點(diǎn),他每次使用完一次上鎖的房間后會(huì)馬上把鑰匙還回去。即使他要連 續(xù)使用兩間上鎖的房間,中間他也要把鑰匙還回去,再取回來。
因此,普通情況下鑰匙的使用原則是:“隨用隨借,用完即還。”
這時(shí)其他人可以不受限制的使用那些不上鎖的房間,一個(gè)人用一間可以,兩個(gè)人用一間也可以,沒限制。但是如果當(dāng)某個(gè)人想要進(jìn)入上鎖的房間,他就要跑到大門口去看看了。有鑰匙當(dāng)然拿了就走,沒有的話,就只能等了。
當(dāng)多線程搶占方法體內(nèi)的資源時(shí),只有獲取key這個(gè)對象的線程才可以獲得并執(zhí)行方法體中的內(nèi)容,其它的線程必須等待這個(gè)線程執(zhí)行完畢后歸還key對象,才可以申請獲得這個(gè)key來搶占資源。
二、同步方法
同步方法的語法格式:public synchronized 數(shù)據(jù)返回類型 方法名(){} 。就是使用 synchronized 這個(gè)關(guān)鍵字來修飾某個(gè)方法,則該方法稱為同步方法。對于同步方法而言,無需顯示指定同步監(jiān)視器,這個(gè)同步監(jiān)視器也就是同步代碼塊中的“key”;同步方法的同步監(jiān)視器是 this 也就是當(dāng)前對象,通過使用同步方法,可非常方便的將某類變成線程安全的類,具有如下特征:
1,該類的對象可以被多個(gè)線程安全的訪問。
2,每個(gè)線程調(diào)用該對象的任意方法之后,都將得到正確的結(jié)果。
3,每個(gè)線程調(diào)用該對象的任意方法之后,該對象狀態(tài)依然保持合理狀態(tài)。
注:synchronized關(guān)鍵字可以修飾方法,也可以修飾代碼塊,但不能修飾構(gòu)造器,屬性等。
三、同步鎖
在Jdk1.5之后,java提供了一個(gè)強(qiáng)大的線程同步機(jī)制:通過顯式定義同步鎖對象來實(shí)現(xiàn)同步,在這種機(jī)制下,同步鎖由Lock對象充當(dāng)。
鎖,提供了對共享資源的獨(dú)占訪問,每次只能有一個(gè)線程對Lock對象加鎖,線程開始訪問共享資源之前應(yīng)該首先獲Lock對象。
某些鎖可能允許對共享資源并發(fā)訪問,如ReadWriteLock(讀寫鎖)。Jdk1.8之后新增了新型的StampedLock。它在大多數(shù)場景中可以替代傳統(tǒng)的ReentranReadWriteLock。為讀寫操作提供三種鎖模式:Writing、ReadingOptimistic、Reading。
當(dāng)產(chǎn)生Lock對象時(shí),我們可以直接通過Lock對象的lock()方法和unlock()方法就可以實(shí)現(xiàn)對資源的上鎖和解鎖過程。