聊聊高并发(十六)实现一个简单的可重入锁
可重入鎖指的是假設(shè)一個(gè)線程已經(jīng)獲得了一個(gè)鎖,那么它能夠多次進(jìn)入這個(gè)鎖,當(dāng)然前提是線程須要先獲得這個(gè)鎖。
可重入鎖是最常使用的鎖。Java的內(nèi)置鎖就是可重入鎖,使用synchronizedkeyword能夠啟用內(nèi)置鎖機(jī)制,比方說(shuō)一個(gè)類有兩個(gè)synchronized方法A和B。在A方法中調(diào)用了B方法,假設(shè)鎖不是可重入的。那么訪問(wèn)B時(shí)須要再次競(jìng)爭(zhēng)鎖。這樣會(huì)帶來(lái)死鎖。
public synchronized void A(){B();}public synchronized void B(){}可重入鎖攻克了這個(gè)問(wèn)題,它使用一個(gè)計(jì)數(shù)器來(lái)記錄一個(gè)線程進(jìn)入鎖的次數(shù),每次進(jìn)入鎖計(jì)數(shù)器就加1。釋放鎖減1。直到計(jì)數(shù)器為0時(shí)表示真正釋放了鎖。其它鎖看到計(jì)數(shù)器不為0時(shí)就知道有其它線程已經(jīng)獲得了鎖。就須要等待。Java的內(nèi)置鎖的基本原理也是這樣,JDK1.5之后提供了顯式鎖ReentrantLock也是這個(gè)基本原理。
以下實(shí)現(xiàn)一個(gè)簡(jiǎn)單的可重入鎖。
1. 使用一個(gè)Thread引用指向獲得鎖的線程
2. 使用一個(gè)計(jì)數(shù)器記錄一個(gè)線程進(jìn)入鎖的次數(shù),當(dāng)計(jì)數(shù)器為0時(shí)表示鎖是空暇的
3. 使用一個(gè)內(nèi)部鎖Lock來(lái)同步線程
4. 使用一個(gè)isHoldZero的條件來(lái)進(jìn)行條件隊(duì)列操作
5. 當(dāng)獲得鎖的線程是自己時(shí),僅僅改動(dòng)計(jì)數(shù)器的值,直接獲得鎖
6. 當(dāng)獲得鎖的線程不是自己時(shí)。須要在holdCount !=0 這個(gè)條件謂詞上等待。直到計(jì)數(shù)器歸0,再次競(jìng)爭(zhēng)鎖
7. 釋放鎖時(shí)計(jì)數(shù)器減1,當(dāng)計(jì)數(shù)器為0時(shí)。喚醒在條件隊(duì)列中等待的線程
package com.zc.lock;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;/*** 簡(jiǎn)單的可重入鎖實(shí)現(xiàn),使用一個(gè)計(jì)數(shù)器記錄當(dāng)前線程重入鎖的次數(shù),獲得鎖時(shí)計(jì)數(shù)器加1,釋放鎖時(shí)計(jì)數(shù)器減1。當(dāng)計(jì)數(shù)器等于0時(shí)表示釋放了鎖* **/
public class SimpleReentrantLock implements Lock{// 指向已經(jīng)獲得鎖的線程private volatile Thread exclusiveOwnerThread;// 記錄獲取了同一個(gè)鎖的次數(shù)private volatile int holdCount;private final java.util.concurrent.locks.Lock lock;// 是否是自己獲得鎖的條件private final Condition isCountZero;public SimpleReentrantLock(){lock = new ReentrantLock();isCountZero = lock.newCondition();holdCount = 0;}@Overridepublic void lock() {lock.lock();try{// 當(dāng)前線程的引用Thread currentThread = Thread.currentThread();// 假設(shè)獲得鎖的線程是自己,那么計(jì)數(shù)器加1,直接返回if(exclusiveOwnerThread == currentThread){holdCount ++;return;}while(holdCount != 0){try {isCountZero.await();} catch (InterruptedException e) {throw new RuntimeException("Interrupted");}}// 將exclusiveOwnerThread設(shè)置為自己exclusiveOwnerThread = currentThread;holdCount ++;}finally{lock.unlock();}}@Overridepublic void unlock() {lock.lock();try{holdCount --;if(holdCount == 0){isCountZero.signalAll();}}finally{lock.unlock();}}}轉(zhuǎn)載于:https://www.cnblogs.com/gcczhongduan/p/5080648.html
總結(jié)
以上是生活随笔為你收集整理的聊聊高并发(十六)实现一个简单的可重入锁的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: “何堪最长夜”下一句是什么
- 下一篇: ORA-00942:表或视图不存在(低级