一、為什么要線程同步?
當(dāng)使用多個(gè)線程來訪問同一個(gè)數(shù)據(jù)時(shí),非常容易出現(xiàn)線程安全問題(比如多個(gè)線程都在操作同一數(shù)據(jù)導(dǎo)致數(shù)據(jù)不一致),所以我們用同步機(jī)制來解決這些問題。 比如一些讀寫操作。
二、名詞解釋:
同步:協(xié)同步調(diào),按預(yù)定的先后次序進(jìn)行運(yùn)行,協(xié)同、協(xié)助、互相配合的意思。如:你說完,我再說。而線程同步呢,就是線程排隊(duì)執(zhí)行,避免同時(shí)對(duì)共享資源進(jìn)行操作。
異步:異步處理不用阻塞當(dāng)前線程來等待處理完成,而是允許后續(xù)操作,直至其它線程將處理完成,并回調(diào)通知此線程。
三、場(chǎng)景:
多線程并發(fā)時(shí),多個(gè)線程同時(shí)請(qǐng)求同一個(gè)資源,會(huì)導(dǎo)致此資源的數(shù)據(jù)混亂,A線程修改B線程的處理的數(shù)據(jù),而B線程又修改A線程處理的數(shù)理。這是由于全局資源造成的,為了解決此問題,優(yōu)先考慮使用局部變量,或者使用同步方法、同步代碼塊、等線程的同步機(jī)制。
同步:A線程要請(qǐng)求某個(gè)資源,但是此資源正在被B線程使用中,因?yàn)橥綑C(jī)制存在,A線程請(qǐng)求不到,怎么辦,A線程只能等待下去
異步:A線程要請(qǐng)求某個(gè)資使用同步對(duì)象源,但是此資源正在被B線程使用中,因?yàn)闆]有同步機(jī)制存在,A線程仍然請(qǐng)求的到,A線程無需等待
四、同步機(jī)制的具體實(shí)現(xiàn):
1、synchronized 同步方法,
2、synchronized 同步塊,
3、synchronized 同步對(duì)象? (其實(shí)就是將對(duì)象的當(dāng)前實(shí)例作為同步鎖,而static synchronized控制類的所有實(shí)例的訪問)
4、使用 volatile 關(guān)鍵詞修飾的變量
5、使用ReentrantLock 主動(dòng)加鎖和釋放鎖
注:synchronized關(guān)鍵字可以修飾方法,也可以修飾代碼塊,但不能修飾構(gòu)造器,屬性等。synchronized關(guān)鍵字是不能繼承的,繼承時(shí)子類的覆蓋方法必須顯示定義成synchronized。
五:注意點(diǎn)
實(shí)現(xiàn)同步機(jī)制注意以下幾點(diǎn):
1、線程同步是非常耗費(fèi)資源的一種操作。我們要盡量控制線程同步的代碼段范圍。同步的代碼段范圍越小越好。(同步鎖競(jìng)爭(zhēng))
2,不要對(duì)線程安全類的所有方法都進(jìn)行同步,只對(duì)那些會(huì)改變共享資源方法的進(jìn)行同步。
3,安全性高,性能低,在多線程用。性能高,安全性低,在單線程用。
4、如果可變類有兩種運(yùn)行環(huán)境,單線程環(huán)境和多線程環(huán)境則應(yīng)該為該可變類提供兩種版本:在單線程中環(huán)境中,使用線程不安全版本以保證性能,在多線程中使用線程安全版本保證安全。
5、多個(gè)線程訪問共享資源的代碼有可能是同一份代碼,但如果訪問同一份共享資源的是不同的代碼段,應(yīng)該加上同一個(gè)同步鎖;如果加的是不同的同步鎖,那么根本就起不到同步的作用,沒有任何意義。也就是說 同步鎖本身也一定是多個(gè)線程之間的共享對(duì)象。
6、如果一個(gè)同步代碼塊和非同步代碼塊同時(shí)操作共享資源,仍然會(huì)造成對(duì)共享資源的競(jìng)爭(zhēng)。
六:其他
ThreadLocal與同步機(jī)制
ThreadLocal與同步機(jī)制都是為了解決多線程中相同變量的訪問沖突問題,前者采用以"空間換時(shí)間"的方法,后者采用以"時(shí)間換空間"的方式
線程狀態(tài)圖
多個(gè)線程有同一個(gè)同步代碼塊時(shí),需要在就緒隊(duì)列等待執(zhí)行。執(zhí)行完成,釋放鎖,讓下一個(gè)線程獲取,執(zhí)行。
