日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

聊聊高并发(十六)实现一个简单的可重入锁

發(fā)布時(shí)間:2023/11/27 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 聊聊高并发(十六)实现一个简单的可重入锁 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

可重入鎖指的是假設(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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。