java 實(shí)現(xiàn)線程同步的方式有哪些
更新時(shí)間:2012年11月28日 14:44:56 作者:
當(dāng)使用多個(gè)線程來訪問同一個(gè)數(shù)據(jù)時(shí),非常容易出現(xiàn)線程安全問題,所以我們用同步機(jī)制來解決這些問題,本文將詳細(xì)介紹,需要的朋友可以參考下
什么是線程同步?
當(dāng)使用多個(gè)線程來訪問同一個(gè)數(shù)據(jù)時(shí),非常容易出現(xiàn)線程安全問題(比如多個(gè)線程都在操作同一數(shù)據(jù)導(dǎo)致數(shù)據(jù)不一致),所以我們用同步機(jī)制來解決這些問題。
實(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)境中,使用線程不安全版本以保證性能,在多線程中使用線程安全版本.
線程通訊:
為什么要使用線程通訊?
當(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í)行被喚醒的線程
當(dāng)使用多個(gè)線程來訪問同一個(gè)數(shù)據(jù)時(shí),非常容易出現(xiàn)線程安全問題(比如多個(gè)線程都在操作同一數(shù)據(jù)導(dǎo)致數(shù)據(jù)不一致),所以我們用同步機(jī)制來解決這些問題。
實(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)境中,使用線程不安全版本以保證性能,在多線程中使用線程安全版本.
線程通訊:
為什么要使用線程通訊?
當(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í)行被喚醒的線程
相關(guān)文章
淺談Spring Security 對于靜態(tài)資源的攔截與放行
這篇文章主要介紹了淺談Spring Security 對于靜態(tài)資源的攔截與放行,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
解決Nacos在執(zhí)行startup.cmd的時(shí)候出現(xiàn)閃退的問題
因?yàn)樵诠ぷ髦械捻?xiàng)目中需要使用到nacos作為注冊中心,但是在使用nacos的過程中運(yùn)行startup.cmd的時(shí)候出現(xiàn)了閃退的情況,運(yùn)行startup.cmd閃一下就沒有了,我把解決這個(gè)問題的全過程理了一下,希望能幫到您,需要的朋友可以參考下2023-12-12
mybatis使用foreach語句實(shí)現(xiàn)IN查詢(三種)
這篇文章主要介紹了mybatis使用foreach語句實(shí)現(xiàn)IN查詢(三種),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
在Java開發(fā)中無法繞開的SpringBoot框架詳解
SpringBoot是一個(gè)基于Spring框架的快速開發(fā)框架,它的出現(xiàn)極大地簡化了Spring應(yīng)用的開發(fā)流程,SpringBoot是一個(gè)快速開發(fā)的框架,它提供了一種快速構(gòu)建應(yīng)用程序的方式,本文給大家介紹在Java開發(fā)中無法繞開的框架:SpringBoot,感興趣的朋友一起看看吧2023-09-09
redis之基于SpringBoot實(shí)現(xiàn)Redis stream實(shí)時(shí)流事件處理方式
這篇文章主要介紹了redis之基于SpringBoot實(shí)現(xiàn)Redis stream實(shí)時(shí)流事件處理方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
9個(gè)SpringBoot中的自帶實(shí)用過濾器使用詳解
在SpringBoot應(yīng)用中,過濾器(Filter)是處理HTTP請求和響應(yīng)的重要組件,SpringBoot自帶了許多實(shí)用的過濾器,如字符編碼,跨域請求,緩存控制等,下面我們就來看看它的具體使用吧2025-05-05

