wait():使一個(gè)線程處于等待狀態(tài),并且釋放所持有的對象的lock。
sleep():使一個(gè)正在運(yùn)知行的線程處于睡眠狀態(tài),是一個(gè)靜態(tài)方法,調(diào)用此道方法要捕捉InterruptedException異常。
notify():喚醒一個(gè)處于等待狀態(tài)的線程,注意的是在調(diào)用此方法的時(shí)候,并不專能確切的喚醒某一個(gè)等待狀態(tài)的線程,而是由JVM確定喚醒哪個(gè)線程,而且不是按優(yōu)先級。
Allnotity():喚醒所有處入等待狀態(tài)的線程,注意并不是給所有喚醒線程一個(gè)對象的鎖,而是讓屬它們競爭。
1。同步代碼塊:
synchronized(同一個(gè)數(shù)據(jù)){} 同一個(gè)數(shù)據(jù):就是N條線程同時(shí)訪問一個(gè)數(shù)據(jù)。
2。
同步方法:
public synchronized 數(shù)據(jù)返回類型 方法名(){}
就
是使用 synchronized 來修飾某個(gè)方法,則該方法稱為同步方法。對于同步方法而言,無需顯示指定同步監(jiān)視器,同步方法的同步監(jiān)視器是
this
也就是該對象的本身(這里指的對象本身有點(diǎn)含糊,其實(shí)就是調(diào)用該同步方法的對象)通過使用同步方法,可非常方便的將某類變成線程安全的類,具有如下特征:
1,該類的對象可以被多個(gè)線程安全的訪問。
2,每個(gè)線程調(diào)用該對象的任意方法之后,都將得到正確的結(jié)果。
3,每個(gè)線程調(diào)用該對象的任意方法之后,該對象狀態(tài)依然保持合理狀態(tài)。
注:synchronized關(guān)鍵字可以修飾方法,也可以修飾代碼塊,但不能修飾構(gòu)造器,屬性等。
實(shí)現(xiàn)同步機(jī)制注意以下幾點(diǎn): 安全性高,性能低,在多線程用。性能高,安全性低,在單線程用。
1,不要對線程安全類的所有方法都進(jìn)行同步,只對那些會改變共享資源方法的進(jìn)行同步。
2,如果可變類有兩種運(yùn)行環(huán)境,當(dāng)線程環(huán)境和多線程環(huán)境則應(yīng)該為該可變類提供兩種版本:線程安全版本和線程不安全版本(沒有同步方法和同步塊)。在單線程中環(huán)境中,使用線程不安全版本以保證性能,在多線程中使用線程安全版本.
線程通訊:
為什么要使用線程通訊?
當(dāng)
使用synchronized
來修飾某個(gè)共享資源時(shí)(分同步代碼塊和同步方法兩種情況),當(dāng)某個(gè)線程獲得共享資源的鎖后就可以執(zhí)行相應(yīng)的代碼段,直到該線程運(yùn)行完該代碼段后才釋放對該
共享資源的鎖,讓其他線程有機(jī)會執(zhí)行對該共享資源的修改。當(dāng)某個(gè)線程占有某個(gè)共享資源的鎖時(shí),如果另外一個(gè)線程也想獲得這把鎖運(yùn)行就需要使用wait()
和notify()/notifyAll()方法來進(jìn)行線程通訊了。
Java.lang.object 里的三個(gè)方法wait() notify() notifyAll()
wait方法導(dǎo)致當(dāng)前線程等待,直到其他線程調(diào)用同步監(jiān)視器的notify方法或notifyAll方法來喚醒該線程。
wait(mills)方法
都是等待指定時(shí)間后自動蘇醒,調(diào)用wait方法的當(dāng)前線程會釋放該同步監(jiān)視器的鎖定,可以不用notify或notifyAll方法把它喚醒。
notify()
喚醒在同步監(jiān)視器上等待的單個(gè)線程,如果所有線程都在同步監(jiān)視器上等待,則會選擇喚醒其中一個(gè)線程,選擇是任意性的,只有當(dāng)前線程放棄對該同步監(jiān)視器的鎖定后,也就是使用wait方法后,才可以執(zhí)行被喚醒的線程。
notifyAll()方法
喚醒在同步監(jiān)視器上等待的所有的線程。只用當(dāng)前線程放棄對該同步監(jiān)視器的鎖定后,才可以執(zhí)行被喚醒的線程
一、java允許多線程并發(fā)控制,當(dāng)多個(gè)線程同時(shí)操作一個(gè)可共享的資源變量時(shí)(如數(shù)據(jù)的增刪改查),
將會導(dǎo)致數(shù)據(jù)不準(zhǔn)確,相互之間產(chǎn)生沖突,因此加入同步鎖以避免在該線程沒有完成操作之前,被其他線程的調(diào)用, 從而保證了該變量的唯一性和準(zhǔn)確性。
二、實(shí)現(xiàn)方法:
1、同步方法
即有synchronized關(guān)鍵字修飾的方法。
由于java的每個(gè)對象都有一個(gè)內(nèi)置鎖,當(dāng)用此關(guān)鍵字修飾方法時(shí),內(nèi)置鎖會保護(hù)整個(gè)方法。在調(diào)用該方法前,需要獲得內(nèi)置鎖,否則就處于阻塞狀態(tài)。
代碼如: public synchronized void save(){}123
注: synchronized關(guān)鍵字也可以修飾靜態(tài)方法,此時(shí)如果調(diào)用該靜態(tài)方法,將會鎖住整個(gè)類
2、同步代碼塊
即有synchronized關(guān)鍵字修飾的語句塊。被該關(guān)鍵字修飾的語句塊會自動被加上內(nèi)置鎖,從而實(shí)現(xiàn)同步。
3、使用特殊域變量(volatile)實(shí)現(xiàn)線程同步
1)volatile關(guān)鍵字為域變量的訪問提供了一種免鎖機(jī)制;
2)使用volatile修飾域相當(dāng)于告訴虛擬機(jī)該域可能會被其他線程更新,
3)因此每次使用該域就要重新計(jì)算,而不是使用寄存器中的值
4)volatile不會提供任何原子操作,它也不能用來修飾final類型的變量
4、使用重入鎖實(shí)現(xiàn)線程同步
在JavaSE5.0中新增了一個(gè)java.util.concurrent包來支持同步。
ReentrantLock類是可重入、互斥、實(shí)現(xiàn)了Lock接口的鎖,它與使用synchronized方法和快具有相同的基本行為和語義,并且擴(kuò)展了其能力
5、使用局部變量實(shí)現(xiàn)線程同步
如果使用ThreadLocal管理變量,則每一個(gè)使用該變量的線程都獲得該變量的副本,副本之間相互獨(dú)立,這樣每一個(gè)線程都可以隨意修改自己的變量副本,而不會對其他線程產(chǎn)生影響。
實(shí)現(xiàn)同步機(jī)制有兩個(gè)方法:
1、同步代碼塊:
synchronized(同一個(gè)數(shù)據(jù)){} 同一個(gè)數(shù)據(jù):就是N條線程同時(shí)訪問一個(gè)數(shù)據(jù)。
2、同步方法:
public synchronized 數(shù)據(jù)返回類型 方法名(){}
就是使用 synchronized 來修飾某個(gè)方法,則該方法稱為同步方法。對于同步方法而言,無需顯示指定同步監(jiān)視器,同步方法的同步監(jiān)視器是 this 也就是該對象的本身(這里指的對象本身有點(diǎn)含糊,其實(shí)就是調(diào)用該同步方法的對象)通過使用同步方法,可非常方便的將某類變成線程安全的類,具有如下特征:
1,該類的對象可以被多個(gè)線程安全的訪問。
2,每個(gè)線程調(diào)用該對象的任意方法之后,都將得到正確的結(jié)果。
3,每個(gè)線程調(diào)用該對象的任意方法之后,該對象狀態(tài)依然保持合理狀態(tài)。
注:synchronized關(guān)鍵字可以修飾方法,也可以修飾代碼塊,但不能修飾構(gòu)造器,屬性等。
實(shí)現(xiàn)同步機(jī)制注意以下幾點(diǎn): 安全性高,性能低,在多線程用。性能高,安全性低,在單線程用。
1,不要對線程安全類的所有方法都進(jìn)行同步,只對那些會改變共享資源方法的進(jìn)行同步。
2,如果可變類有兩種運(yùn)行環(huán)境,當(dāng)線程環(huán)境和多線程環(huán)境則應(yīng)該為該可變類提供兩種版本:線程安全版本和線程不安全版本(沒有同步方法和同步塊)。在單線程中環(huán)境中,使用線程不安全版本以保證性能,在多線程中使用線程安全版本.
聲明:本網(wǎng)站尊重并保護(hù)知識產(chǎn)權(quán),根據(jù)《信息網(wǎng)絡(luò)傳播權(quán)保護(hù)條例》,如果我們轉(zhuǎn)載的作品侵犯了您的權(quán)利,請?jiān)谝粋€(gè)月內(nèi)通知我們,我們會及時(shí)刪除。
蜀ICP備2020033479號-4 Copyright ? 2016 學(xué)習(xí)鳥. 頁面生成時(shí)間:3.474秒