詳細介紹Java中的各種鎖
更新時間:2021年06月22日 14:09:30 作者:小小蝸牛139
不少同學(xué)開始慢慢接觸多線時候,對線程之間為了保障數(shù)據(jù)安全性,一致性有所了解,本文詳細解介紹java中的21種鎖
,需要的朋友可以參考下
一、一張圖了解21種鎖
二、樂觀鎖
應(yīng)用 CAS 思想 一種樂觀思想,假定當(dāng)前環(huán)境是讀多寫少,遇到并發(fā)寫的概率比較低,讀數(shù)據(jù)時認為別的線程不會正在進行修改 實現(xiàn) 寫數(shù)據(jù)時,判斷當(dāng)前 與期望值是否相同,如果相同則進行更新(更新期間加鎖,保證是原子性的)
三、悲觀鎖
應(yīng)用 synchronized、vector、hashtable 思想: 一種悲觀思想 ** ,即認為寫多讀少,遇到并發(fā)寫的可能性高 實現(xiàn) 每次讀寫數(shù)據(jù)都會認為其他線程會修改,所以每次讀寫數(shù)據(jù)時都會上鎖 缺點 他線程想要讀寫這個數(shù)據(jù)時,會被這個線程block,直到這個線程釋放鎖然后其他線程獲取到鎖
四、自旋鎖
應(yīng)用 CAS 實現(xiàn) 為了讓線程等待,我們只須讓線程執(zhí)行一個忙循環(huán) 優(yōu)點 避免了線程切換的開銷,掛起線程和恢復(fù)線程的操作都需要轉(zhuǎn)入內(nèi)核態(tài)中完成,這些操作給Java虛擬機的并發(fā)性能帶來了很大的壓力 缺點 占用處理器的時間,如果占用的時間很長,會白白消耗處理器資源,而不會做任何有價值的工作,帶來性能的浪費 改進 自旋等待的時間必須有一定的限度,如果自旋超過了限定的次數(shù)仍然沒有成功獲得鎖,就應(yīng)當(dāng)使用傳統(tǒng)的方式去掛起線程 jvm調(diào)優(yōu) -XX:PreBlockSpin 設(shè)置固定失敗次數(shù) 自適應(yīng)自旋 前一次在同一個鎖上的自旋時間及鎖的擁有者的狀態(tài)來決定的,通過系統(tǒng)監(jiān)控進行調(diào)整
五、悲觀鎖
應(yīng)用 synchronized、vector、hashtable 思想: 一種悲觀思想 ** ,即認為寫多讀少,遇到并發(fā)寫的可能性高 實現(xiàn) 每次讀寫數(shù)據(jù)都會認為其他線程會修改,所以每次讀寫數(shù)據(jù)時都會上鎖 缺點 他線程想要讀寫這個數(shù)據(jù)時,會被這個線程block,直到這個線程釋放鎖然后其他線程獲取到鎖
六、可重入鎖(遞歸鎖)
應(yīng)用 synchronized、Reentrantlock、Lock 思想: 任意線程在獲取到鎖之后能夠再次獲取該鎖而不會被鎖所阻塞 實現(xiàn) 通過組合自定義同步器來實現(xiàn)鎖的獲取與釋放 獲取鎖:識別獲取鎖的線程是否為當(dāng)前占據(jù)鎖的線程 ,如果是,則再次成功獲,。獲取鎖后,進行計數(shù)自增 釋放鎖:釋放鎖時,進行計數(shù)自減 優(yōu)點: 避免死鎖 缺點 他線程想要讀寫這個數(shù)據(jù)時,會被這個線程block,直到這個線程釋放鎖然后其他線程獲取到鎖
七、讀寫鎖
應(yīng)用 ReentrantReadWriteLock,CopyOnWriteArrayList、CopyOnWriteArraySet 思想 讀寫分離 實現(xiàn) Java 提供了讀寫鎖,在讀的地方使用讀鎖,在寫的地方使用寫鎖 讀鎖: 允許多個線程獲取讀鎖,同時訪問同一個 寫鎖: 只允許一個線程獲取寫鎖,不允許同時訪問同一個資源 優(yōu)點: 避免死鎖 缺點 他線程想要讀寫這個數(shù)據(jù)時,會被這個線程block,直到這個線程釋放鎖然后其他線程獲取到鎖
八、公平鎖
應(yīng)用 Reentrantlock(true) 思想 多個線程按照申請鎖的順序來獲取鎖 實現(xiàn) 在并發(fā)環(huán)境中,每個線程會先查看此鎖維護的等待隊列,如果當(dāng)前等待隊列為空,則占有鎖,如果等待隊列不為空,則加入到等待隊列的末尾, 按照FIFO的原則從 隊列中拿到線程,然后占有鎖
九、非公平鎖
應(yīng)用 synchronized、reentrantlock(false) 思想 線程嘗試獲取鎖,如果獲取不到,則再采用公平鎖的方式 實現(xiàn) 多個線程獲取鎖的順序,不是按照先到先得的順序,有可能后申請鎖的線程比先申請的線程優(yōu)先獲取鎖
十、共享鎖
應(yīng)用 ReentrantReadWriteLock中讀鎖 思想 可以有多個線程獲取讀鎖,以共享的方式持有鎖
十一、獨鎖
應(yīng)用 synchronized、vector、hashtable、ReentrantReadWriteLock中寫鎖 思想 是一種思想: 只能有一個線程獲取鎖,以獨占的方式持有鎖
十二、重量級鎖
應(yīng)用 synchronized 思想 synchronized是通過對象內(nèi)部的一個叫做監(jiān)視器鎖(monitor)來實現(xiàn)的,監(jiān)視器鎖本身依賴底層的操作系統(tǒng)的 Mutex Lock來實現(xiàn)。 缺點 操作系統(tǒng)實現(xiàn)線程的切換需要從用戶態(tài)切換到核心態(tài),成本非常高。這種依賴于操作系統(tǒng) Mutex Lock來實現(xiàn)的鎖稱為重量級鎖。 改進 為了優(yōu)化synchonized,引入了輕量級鎖,偏向鎖。
十三、輕級鎖
應(yīng)用 鎖優(yōu)化技術(shù) 思想 輕量級鎖是在無競爭的情況下使用CAS操作去消除同步使用的互斥量。 輕量級是相對于使用操作系統(tǒng)互斥量來實現(xiàn)的重量級鎖而言的。 輕量級鎖在沒有多線程競爭的前提下,減少傳統(tǒng)的重量級鎖使用操作系統(tǒng)互斥量產(chǎn)生的性能消耗。 如果出現(xiàn)兩條以上的線程爭用同一個鎖的情況,那輕量級鎖將不會有效,必須膨脹為重量級鎖。 優(yōu)點 如果沒有競爭,通過CAS操作成功避免了使用互斥量的開銷 缺點 如果存在競爭,除了互斥量本身的開銷外,還額外產(chǎn)生了CAS操作的開銷,因此在有競爭的情況下,輕量級鎖比傳統(tǒng)的重量級鎖更慢
到此這篇關(guān)于詳細介紹Java中的各種鎖的文章就介紹到這了,更多相關(guān)Java鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot快速實現(xiàn)接口消息加密的過程詳解
在項目中,為了保證數(shù)據(jù)的安全,我們常常會對傳遞的數(shù)據(jù)進行加密,常用的加密算法包括對稱加密(AES)和非對稱加密(RSA),博主選取碼云上最簡單的API加密項目進行下面的講解,需要的朋友可以參考下2023-11-11Spring Boot項目集成UidGenerato的方法步驟
這篇文章主要介紹了Spring Boot項目集成UidGenerato的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Linux環(huán)境卸載Centos7自帶的OpenJDK和安裝JDK1.8圖文教程
CentOS系統(tǒng)是開發(fā)者常用的Linux操作系統(tǒng),安裝它時會默認安裝自帶的舊版本的OpenJDK,但在開發(fā)者平時開發(fā)Java項目時還是需要完整的JDK,這篇文章主要給大家介紹了關(guān)于Linux環(huán)境卸載Centos7自帶的OpenJDK和安裝JDK1.8的相關(guān)資料,需要的朋友可以參考下2024-07-07Java函數(shù)式編程(十二):監(jiān)控文件修改
這篇文章主要介紹了Java函數(shù)式編程(十二):監(jiān)控文件修改,本文是系列文章的第12篇,其它文章請參閱本文底部的相關(guān)文章,需要的朋友可以參考下2014-09-09springboot+gradle 構(gòu)建多模塊項目的步驟
這篇文章主要介紹了springboot+gradle 構(gòu)建多模塊項目的步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05