這篇文章主要講解了“什么是AQS、ReentrantLock”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“什么是AQS、ReentrantLock”吧!
創(chuàng)新互聯(lián)主營(yíng)烏魯木齊網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都App制作,烏魯木齊h5微信小程序搭建,烏魯木齊網(wǎng)站營(yíng)銷推廣歡迎烏魯木齊等地區(qū)企業(yè)咨詢
Java并發(fā)編程的核心在于java.concurrent.util包,juc中大多數(shù)同步器的實(shí)現(xiàn)都圍繞了一個(gè)公共的行為,比如等待隊(duì)列、條件隊(duì)列、獨(dú)占獲取、共享獲取等,這個(gè)行為的抽象就是基于AbstractQueuedSynchronized(AQS)。AQS定義了多線程訪問(wèn)共享資源的同步器框架。
簡(jiǎn)單來(lái)講,AQS就好比一個(gè)行為準(zhǔn)則,而并發(fā)包中的大多數(shù)同步器在這個(gè)準(zhǔn)則下實(shí)現(xiàn)。
AQS具備以下的幾個(gè)特性:阻塞等待隊(duì)列、共享/獨(dú)占、公平/非公平、可重入、允許中斷。
如果你點(diǎn)開(kāi)JUC發(fā)源碼,會(huì)發(fā)現(xiàn)大量同步器的實(shí)現(xiàn),比如:Lock、Latch、Barrier等都基于AQS實(shí)現(xiàn)。
在AQS中,我們需要記住幾個(gè)重要的知識(shí)點(diǎn):
1、AQS的實(shí)現(xiàn)通常是定義內(nèi)部類Sync繼承AQS,將同步器的所有調(diào)用都映射到Sync對(duì)應(yīng)的方法上。
2、AQS內(nèi)部有個(gè)屬性叫state,表示資源的可用狀態(tài)。state有三種訪問(wèn)方式getState()、setState()、compareAndSetState()
3、AQS定義了兩種資源的共享方式:獨(dú)占(Exclusive)如ReentrantLock、共享(Share)如Semaphore或CountDownLatch
4、AQS中定義了同步等待隊(duì)列,用于存放等待線程的一個(gè)隊(duì)列。
這幾個(gè)知識(shí)點(diǎn)會(huì)在后面的內(nèi)容中使用到。
我們通過(guò)ReentrantLock這個(gè)示例來(lái)更深入的了解AQS。我會(huì)通過(guò)上面四個(gè)知識(shí)點(diǎn)去講解ReentrantLock中AQS的使用。
1、首先進(jìn)入ReentrantLock的源碼內(nèi)部,直接就能看到ReentrantLock中定義的內(nèi)部類Sync
Sync繼承了AQS,按AQS去指定同步規(guī)則。
2、既然繼承了AQS,ReentrantLock內(nèi)部也相當(dāng)于有了state,這個(gè)state用來(lái)記錄上鎖的次數(shù),ReentrantLock是個(gè)可重入鎖,如果多次上鎖,state會(huì)記錄上鎖的次數(shù),需要釋放同樣次數(shù)的鎖才算把鎖釋放完。
3、ReentrantLock的資源是獨(dú)占的,AbstractQueuedSynchronized繼承了一個(gè)叫AbstractOwnableSynchronizer的抽象類:
在這個(gè)類中,有個(gè)變量叫exclusiveOwnerThread,這個(gè)變量記錄著當(dāng)前是哪個(gè)線程獨(dú)占了鎖。
4、同步等待隊(duì)列:由于ReentrantLock是個(gè)獨(dú)占的鎖,當(dāng)有一個(gè)線程在使用這個(gè)鎖的時(shí)候,其他線程就要到隊(duì)列中去等待,這個(gè)隊(duì)列是一種基于雙向鏈表的隊(duì)列(類CLH隊(duì)列),節(jié)點(diǎn)中存放線程信息。
在介紹AQS時(shí),我們講到了AQS中有個(gè)狀態(tài)值state,這個(gè)值用來(lái)判斷當(dāng)前資源的可用狀態(tài)??芍厝腈i的意思就是對(duì)一個(gè)對(duì)象可以實(shí)現(xiàn)多次加鎖,state就用來(lái)記錄加鎖的次數(shù)。下面寫(xiě)一段代碼:
public class ReentrantLockTest { //定義全局的鎖對(duì)象 private static final Lock lock=new ReentrantLock(true); public static int count=0; public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { testlock(); } },"線程A").start(); new Thread(new Runnable() { @Override public void run() { testlock(); } },"線程B").start(); } private static void testlock() { lock.lock(); count++; System.out.println(Thread.currentThread().getName()+"第一次加鎖"+count); lock.lock(); count++; System.out.println(Thread.currentThread().getName()+"第二次加鎖"+count); count--; lock.unlock(); System.out.println(Thread.currentThread().getName()+"第一次解鎖"+count); count--; lock.unlock(); System.out.println(Thread.currentThread().getName()+"第二次解鎖"+count); } }
生成兩個(gè)線程,讓他們?nèi)?zhí)行testlock方法,然后在testlock方法的開(kāi)始和結(jié)束加鎖,保證同時(shí)只有一個(gè)線程可以執(zhí)行里面的方法。最后的結(jié)果是線程有序執(zhí)行:
在代碼中,我們進(jìn)行了兩次lock,這就是可重入鎖。我們通過(guò)斷點(diǎn)調(diào)試,來(lái)分析第二次加鎖后lock中的值,下面給出了說(shuō)明。
我們?cè)谟脴?gòu)造方法創(chuàng)建ReentrantLock的時(shí)候,可以傳入一個(gè)boolean類型的參數(shù),true或false
private static final Lock lock=new ReentrantLock(true);
這里的true和false代表了創(chuàng)建的ReentrantLock對(duì)象是公平鎖還是非公平鎖
感謝各位的閱讀,以上就是“什么是AQS、ReentrantLock”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)什么是AQS、ReentrantLock這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
當(dāng)前標(biāo)題:什么是AQS、ReentrantLock
當(dāng)前URL:http://www.rwnh.cn/article38/jeeopp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、Google、面包屑導(dǎo)航、移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)