是用來實現鎖或者其它同步器組件的公共基礎部分的抽象實現,整體就是一個抽象的FIFO隊列來完成資源獲取線程的安排工作,并通過一個int類變量表示持有鎖的狀態。
ReentranLock:
CountDownLatch
ReentrantReadWriteLock:
Semaphore
搶到資源的線程直接使用處理業務,搶不到資源的必然涉及一種排隊等候機制。搶占資源失敗的線程繼續去等待(類似銀行業務辦理窗口都滿了,暫時沒有受理窗口的顧客只能去候客區排隊等候),但等候線程仍然保留獲取鎖的可能且獲取鎖流程仍在繼續(候客區的顧客也在等著叫號,輪到了再去受理窗口辦理業務)
如果共享資源被占用,就需要一定的阻塞等待喚醒機制來保證鎖分配。這個機制主要用的是CLH隊列的變體實現的,將暫時獲取不到的鎖的線程加入到隊列中,這個隊列就是AQS同步隊列的抽象表現。它將要請求共享資源的線程及自身的等待狀態封裝成隊列的結點對象(Node),通過CAS、自旋以及LockSupport.park()的方式,維護state變量的狀態,使并發達到同步的效果。
第一步:
第二步:創建的是公平鎖還是非公平鎖
第三:以非公平鎖ReentrantLock()為例作為突破走起,方法lock()
對比公平鎖和非公平鎖的tryAcquire()方法的實現代碼,其實差別就在于非公平鎖獲取鎖時公平鎖中少了一個判斷!hasQueuedPredecessors(),此方法中判斷了是否需要排隊,導致公平鎖和非公平鎖的差異如下:
公平鎖:公平鎖講究先來先到,線程在獲取鎖時,如果這個鎖的等待隊列中已經有線程在等待,那么當前線程就會進入等待隊列中;
非公平鎖:不管是否有等待隊列,如果可以獲取鎖,則立刻占有鎖對象。也就是說隊列的第一個排隊線程蘇醒后,不一定就是排頭的這個線程獲得鎖,它還是需要參加競爭鎖(存在線程競爭的情況下),后來的線程可能不講武德插隊奪鎖了。
第四:線程使用lock方法來加鎖
以下截圖為非公平鎖的
第五:acquire()方法
第六:tryAcquire方法
第六,如果線程使用nonfairTryAcquire方法搶占資源失敗,則使用addWaiter方法將線程加入等待隊列
第一次調用enq方法之后會形成以下的樣子:
第七:acquireQueued()方法
第八:使用unlock方法來釋放鎖
隊列中喚醒的線程再去搶占鎖
你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧
網站標題:Java之AQS-創新互聯
文章來源:http://vcdvsql.cn/article46/ggseg.html
成都網站建設公司_創新互聯,為您提供網站改版、微信小程序、網站策劃、自適應網站、品牌網站制作、網站維護
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯