詳細(xì)介紹Java中的各種鎖
更新時間:2021年06月22日 14:09:30 作者:小小蝸牛139
不少同學(xué)開始慢慢接觸多線時候,對線程之間為了保障數(shù)據(jù)安全性,一致性有所了解,本文詳細(xì)解介紹java中的21種鎖
,需要的朋友可以參考下
一、一張圖了解21種鎖

二、樂觀鎖
應(yīng)用 CAS 思想 一種樂觀思想,假定當(dāng)前環(huán)境是讀多寫少,遇到并發(fā)寫的概率比較低,讀數(shù)據(jù)時認(rèn)為別的線程不會正在進(jìn)行修改 實(shí)現(xiàn) 寫數(shù)據(jù)時,判斷當(dāng)前 與期望值是否相同,如果相同則進(jìn)行更新(更新期間加鎖,保證是原子性的)
三、悲觀鎖
應(yīng)用 synchronized、vector、hashtable 思想: 一種悲觀思想 ** ,即認(rèn)為寫多讀少,遇到并發(fā)寫的可能性高 實(shí)現(xiàn) 每次讀寫數(shù)據(jù)都會認(rèn)為其他線程會修改,所以每次讀寫數(shù)據(jù)時都會上鎖 缺點(diǎn) 他線程想要讀寫這個數(shù)據(jù)時,會被這個線程block,直到這個線程釋放鎖然后其他線程獲取到鎖
四、自旋鎖
應(yīng)用 CAS 實(shí)現(xiàn) 為了讓線程等待,我們只須讓線程執(zhí)行一個忙循環(huán) 優(yōu)點(diǎn) 避免了線程切換的開銷,掛起線程和恢復(fù)線程的操作都需要轉(zhuǎn)入內(nèi)核態(tài)中完成,這些操作給Java虛擬機(jī)的并發(fā)性能帶來了很大的壓力 缺點(diǎn) 占用處理器的時間,如果占用的時間很長,會白白消耗處理器資源,而不會做任何有價值的工作,帶來性能的浪費(fèi) 改進(jìn) 自旋等待的時間必須有一定的限度,如果自旋超過了限定的次數(shù)仍然沒有成功獲得鎖,就應(yīng)當(dāng)使用傳統(tǒng)的方式去掛起線程 jvm調(diào)優(yōu) -XX:PreBlockSpin 設(shè)置固定失敗次數(shù) 自適應(yīng)自旋 前一次在同一個鎖上的自旋時間及鎖的擁有者的狀態(tài)來決定的,通過系統(tǒng)監(jiān)控進(jìn)行調(diào)整
五、悲觀鎖
應(yīng)用 synchronized、vector、hashtable 思想: 一種悲觀思想 ** ,即認(rèn)為寫多讀少,遇到并發(fā)寫的可能性高 實(shí)現(xiàn) 每次讀寫數(shù)據(jù)都會認(rèn)為其他線程會修改,所以每次讀寫數(shù)據(jù)時都會上鎖 缺點(diǎn) 他線程想要讀寫這個數(shù)據(jù)時,會被這個線程block,直到這個線程釋放鎖然后其他線程獲取到鎖
六、可重入鎖(遞歸鎖)
應(yīng)用 synchronized、Reentrantlock、Lock 思想: 任意線程在獲取到鎖之后能夠再次獲取該鎖而不會被鎖所阻塞 實(shí)現(xiàn) 通過組合自定義同步器來實(shí)現(xiàn)鎖的獲取與釋放 獲取鎖:識別獲取鎖的線程是否為當(dāng)前占據(jù)鎖的線程 ,如果是,則再次成功獲,。獲取鎖后,進(jìn)行計數(shù)自增 釋放鎖:釋放鎖時,進(jìn)行計數(shù)自減 優(yōu)點(diǎn): 避免死鎖 缺點(diǎn) 他線程想要讀寫這個數(shù)據(jù)時,會被這個線程block,直到這個線程釋放鎖然后其他線程獲取到鎖
七、讀寫鎖
應(yīng)用 ReentrantReadWriteLock,CopyOnWriteArrayList、CopyOnWriteArraySet 思想 讀寫分離 實(shí)現(xiàn) Java 提供了讀寫鎖,在讀的地方使用讀鎖,在寫的地方使用寫鎖 讀鎖: 允許多個線程獲取讀鎖,同時訪問同一個 寫鎖: 只允許一個線程獲取寫鎖,不允許同時訪問同一個資源 優(yōu)點(diǎn): 避免死鎖 缺點(diǎn) 他線程想要讀寫這個數(shù)據(jù)時,會被這個線程block,直到這個線程釋放鎖然后其他線程獲取到鎖
八、公平鎖
應(yīng)用 Reentrantlock(true) 思想 多個線程按照申請鎖的順序來獲取鎖 實(shí)現(xiàn) 在并發(fā)環(huán)境中,每個線程會先查看此鎖維護(hù)的等待隊(duì)列,如果當(dāng)前等待隊(duì)列為空,則占有鎖,如果等待隊(duì)列不為空,則加入到等待隊(duì)列的末尾, 按照FIFO的原則從 隊(duì)列中拿到線程,然后占有鎖
九、非公平鎖
應(yīng)用 synchronized、reentrantlock(false) 思想 線程嘗試獲取鎖,如果獲取不到,則再采用公平鎖的方式 實(shí)現(xiàn) 多個線程獲取鎖的順序,不是按照先到先得的順序,有可能后申請鎖的線程比先申請的線程優(yōu)先獲取鎖
十、共享鎖
應(yīng)用 ReentrantReadWriteLock中讀鎖 思想 可以有多個線程獲取讀鎖,以共享的方式持有鎖
十一、獨(dú)鎖
應(yīng)用 synchronized、vector、hashtable、ReentrantReadWriteLock中寫鎖 思想 是一種思想: 只能有一個線程獲取鎖,以獨(dú)占的方式持有鎖
十二、重量級鎖
應(yīng)用 synchronized 思想 synchronized是通過對象內(nèi)部的一個叫做監(jiān)視器鎖(monitor)來實(shí)現(xiàn)的,監(jiān)視器鎖本身依賴底層的操作系統(tǒng)的 Mutex Lock來實(shí)現(xiàn)。 缺點(diǎn) 操作系統(tǒng)實(shí)現(xiàn)線程的切換需要從用戶態(tài)切換到核心態(tài),成本非常高。這種依賴于操作系統(tǒng) Mutex Lock來實(shí)現(xiàn)的鎖稱為重量級鎖。 改進(jìn) 為了優(yōu)化synchonized,引入了輕量級鎖,偏向鎖。
十三、輕級鎖
應(yīng)用 鎖優(yōu)化技術(shù) 思想 輕量級鎖是在無競爭的情況下使用CAS操作去消除同步使用的互斥量。 輕量級是相對于使用操作系統(tǒng)互斥量來實(shí)現(xiàn)的重量級鎖而言的。 輕量級鎖在沒有多線程競爭的前提下,減少傳統(tǒng)的重量級鎖使用操作系統(tǒng)互斥量產(chǎn)生的性能消耗。 如果出現(xiàn)兩條以上的線程爭用同一個鎖的情況,那輕量級鎖將不會有效,必須膨脹為重量級鎖。 優(yōu)點(diǎn) 如果沒有競爭,通過CAS操作成功避免了使用互斥量的開銷 缺點(diǎn) 如果存在競爭,除了互斥量本身的開銷外,還額外產(chǎn)生了CAS操作的開銷,因此在有競爭的情況下,輕量級鎖比傳統(tǒng)的重量級鎖更慢
到此這篇關(guān)于詳細(xì)介紹Java中的各種鎖的文章就介紹到這了,更多相關(guān)Java鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot jar 啟動時設(shè)置環(huán)境參數(shù)的操作
這篇文章主要介紹了Spring Boot jar 啟動時設(shè)置環(huán)境參數(shù)的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
使用Java實(shí)現(xiàn)一個解析CURL腳本小工具
文章介紹了如何使用Java實(shí)現(xiàn)一個解析CURL腳本的工具,該工具可以將CURL腳本中的Header解析為KV Map結(jié)構(gòu),獲取URL路徑、請求類型,解析URL參數(shù)列表和Body請求體,感興趣的小伙伴跟著小編一起來看看吧2025-02-02
mybatis 一對一、一對多和多對多查詢實(shí)例代碼
這篇文章主要介紹了mybatis 一對一、一對多和多對多查詢的實(shí)例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-06-06
淺析JAVA常用JDBC連接數(shù)據(jù)庫的方法總結(jié)
本篇文章是對在JAVA中常用JDBC連接數(shù)據(jù)庫的方法進(jìn)行了詳細(xì)的總結(jié)分析,需要的朋友參考下2013-07-07
SpringBoot3集成Swagger3的詳細(xì)教程
Swagger 3(OpenAPI 3.0)提供了更加強(qiáng)大和靈活的API文檔生成能力,本教程將指導(dǎo)您如何在Spring Boot 3項(xiàng)目中集成Swagger3,并使用Knife4j作為UI界面,需要的朋友可以參考下2024-03-03

