java lock 信號_java各種鎖(ReentrantLock,Semaphore,CountDownLatch)的實現原理

先放結論:主要是實現AbstractQueuedSynchronizer中進入和退出函數,控制不同的進入和退出條件,實現適用于各種場景下的鎖。

JAVA中對于線程的同步提供了多種鎖機制,比較著名的有可重入鎖ReentrantLock,信號量機制Semaphore,隊列等待機制CountDownLatch,

通過查看源代碼可以,他們都是基于AbstractQueuedSynchronizer實現了自身的功能。

796dfedd20df3334c2a5ec4ac5538cdd.png

對于AbstractQueuedSynchronizer的講解,可以看上一篇文章,這里就講解下,如何通過集成AbstractQueuedSynchronizer實現上述的鎖機制。

所謂的鎖實現,就是對AbstractQueuedSynchronizer中state變量的搶占,誰先搶占并且修改了這個變量值不為0,誰就獲得了鎖。

AbstractQueuedSynchronizer保留了幾個未實現的接口供子類實現。分別是

protected boolean tryAcquire(intarg) {throw newUnsupportedOperationException();

}protected boolean tryRelease(intarg) {throw newUnsupportedOperationException();

}protected int tryAcquireShared(intarg) {throw newUnsupportedOperationException();

}protected boolean tryReleaseShared(intarg) {throw newUnsupportedOperationException();

}

tryAcquire和tryRelease是用于獨占鎖的獲取和釋放,tryAcquireShared和tryReleaseShared是共享鎖的獲取和釋放,下面看下他們分別是什么地方被調用。

/*** Acquires in exclusive mode, ignoring interrupts. Implemented

* by invoking at least once {@link#tryAcquire},

* returning on success. Otherwise the thread is queued, possibly

* repeatedly blocking and unblocking, invoking {@link* #tryAcquire} until success. This method can be used

* to implement method {@linkLock#lock}.

*

*@paramarg the acquire argument. This value is conveyed to

* {@link#tryAcquire} but is otherwise uninterpreted and

* can represent anything you like.*/

public final void acquire(intarg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))

selfInterrupt();

}/*** Releases in exclusive mode. Implemented by unblocking one or

* more threads if {@link#tryRelease} returns true.

* This method can be used to implement method {@linkLock#unlock}.

*

*@paramarg the release argument. This value is conveyed to

* {@link#tryRelease} but is otherwise uninterpreted and

* can represent anything you like.

*@returnthe value returned from {@link#tryRelease}*/

public final boolean release(intarg) {if(tryRelease(arg)) {

Node h=head;if (h != null && h.waitStatus != 0)

unparkSuccessor(h);return true;

}return false;

}/*** Acquires in shared mode, ignoring interrupts. Implemented by

* first invoking at least once {@link#tryAcquireShared},

* returning on success. Otherwise the thread is queued, possibly

* repeatedly blocking and unblocking, invoking {@link* #tryAcquireShared} until success.

*

*@paramarg the acquire argument. This value is conveyed to

* {@link#tryAcquireShared} but is otherwise uninterpreted

* and can represent anything you like.*/

public final void acquireShared(intarg) {if (tryAcquireShared(arg) < 0)

doAcquireShared(arg);

}/*** Releases in shared mode. Implemented by unblocking one or more

* threads if {@link#tryReleaseShared} returns true.

*

*@paramarg the release argument. This value is conveyed to

* {@link#tryReleaseShared} but is otherwise uninterpreted

* and can represent anything you like.

*@returnthe value returned from {@link#tryReleaseShared}*/

public final boolean releaseShared(intarg) {if(tryReleaseShared(arg)) {

doReleaseShared();return true;

}return false;

}

在acquire中,如果tryAcquire失敗,那么就去等待隊列中排隊,release中如果tryRelease成功,那么就喚醒下一個等待隊列中的線程。

acquireShared中,如果tryAcquireShared失敗,那么再次進入循環獲取過程,releaseShared中,如果tryReleaseShared成功,那么就喚醒下一個等待隊列中的線程。

現在的主要問題是,如何判定上述的tryAcquire、tryRelease、tryAcquireShared和tryReleaseShared的成功和失敗,

通過閱讀源代碼可知:

ReentrantLock是一個線程執行,其他線程等待。

ReentrantLock的實現機制就是:線程lock()時,獲取時state變量的值不為0,那么tryAcquire就失敗,tryRelease執行完state變量的值==0,表示成功,喚醒等待的線程,否則就是失敗。

Semaphore是先分配一定數量的許可證,然后多個線程來搶許可證,搶到就可以執行。

Semaphore的實現機制就是:如果獲取時當前state減去申請的信號量數目acquires>0,那么就表示成功,此時 state=state-acquires, 否則失敗,釋放時,當前釋放的信號量不為負數,那么就表示成功,喚醒等待的線程,釋放后state=state+acquires.

CountDownLatch是一個線程執行,其他線程等待。

CountDownLatch的實現機制是: 線程如果lock()時,獲取時state變量的值不為0,那么tryAcquire就失敗,tryRelease執行完state變量的值等于0或者state-1后值等于0,表示成功,喚醒等待的線程,否則就是失敗。

ReentrantLock的代碼如下:

final boolean nonfairTryAcquire(intacquires) {final Thread current =Thread.currentThread();int c =getState();if (c == 0) {if (compareAndSetState(0, acquires)) {

setExclusiveOwnerThread(current);return true;

}

}else if (current ==getExclusiveOwnerThread()) {int nextc = c +acquires;if (nextc < 0) //overflow

throw new Error("Maximum lock count exceeded");

setState(nextc);return true;

}return false;

}protected final boolean tryRelease(intreleases) {int c = getState() -releases;if (Thread.currentThread() !=getExclusiveOwnerThread())throw newIllegalMonitorStateException();boolean free = false;if (c == 0) {

free= true;

setExclusiveOwnerThread(null);

}

setState(c);returnfree;

}

Semaphore代碼如下:

final int nonfairTryAcquireShared(intacquires) {for(;;) {int available =getState();int remaining = available -acquires;if (remaining < 0 ||compareAndSetState(available, remaining))returnremaining;

}

}protected final boolean tryReleaseShared(intreleases) {for(;;) {int current =getState();int next = current +releases;if (next < current) //overflow

throw new Error("Maximum permit count exceeded");if(compareAndSetState(current, next))return true;

}

}

CountDownLatch代碼如下:

protected int tryAcquireShared(intacquires) {return (getState() == 0) ? 1 : -1;

}protected boolean tryReleaseShared(intreleases) {//Decrement count; signal when transition to zero

for(;;) {int c =getState();if (c == 0)return false;int nextc = c-1;if(compareAndSetState(c, nextc))return nextc == 0;

}

}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/388807.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/388807.shtml
英文地址,請注明出處:http://en.pswp.cn/news/388807.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Intent.ACTION_MAIN

1 Intent.ACTION_MAIN String: android.intent.action.MAIN 標識Activity為一個程序的開始。比較常用。 Input:nothing Output:nothing 例如&#xff1a; 1 <activity android:name".Main"android:label"string/app_name">2 <intent-filter…

足球預測_預測足球熱

足球預測By Aditya Pethe通過阿蒂亞皮特(Aditya Pethe) From September to January every year, football takes over America. Games dominate TV Sunday and Monday nights, and my brother tears his hair out each week over his consistently underperforming fantasy te…

C#的特性Attribute

一、什么是特性 特性是用于在運行時傳遞程序中各種元素&#xff08;比如類、方法、結構、枚舉、組件等&#xff09;的行為信息的聲明性標簽&#xff0c;這個標簽可以有多個。您可以通過使用特性向程序添加聲明性信息。一個聲明性標簽是通過放置在它所應用的元素前面的方括號&am…

java 技能鑒定_JAVA試題-技能鑒定

一、單選題1.以下創建了幾個對象( B)String A,B,CA"a";B"b":AAB;StringBuffer Dnew StringBuffer("abc");DD.append("567");A.6B.4C.3D.52.關于以下程序段&#xff0c;正確的說法是( C )1&#xff0e;String s1“a”“b”;2&#xff0…

ADD_SHORTCUT_ACTION

String ADD_SHORTCUT_ACTION 動作&#xff1a;在系統中添加一個快捷方式。. “android.intent.action.ADD_SHORTCUT”   String ALL_APPS_ACTION 動作&#xff1a;列舉所有可用的應用。   輸入&#xff1a;無。 “android.intent.action.ALL_APPS”   String ALTERNATIVE…

python3中樸素貝葉斯_貝葉斯統計:Python中從零開始的都會都市

python3中樸素貝葉斯你在這里 (You are here) If you’re reading this, odds are: (1) you’re interested in bayesian statistics but (2) you have no idea how Markov Chain Monte Carlo (MCMC) sampling methods work, and (3) you realize that all but the simplest, t…

java映射的概念_Java 反射 概念理解

文章來源:http://hollischuang.gitee.io/tobetopjavaer/#/basics/java-basic/reflection反射反射機制指的是程序在運行時能夠獲取自身的信息。在java中&#xff0c;只要給定類的名字&#xff0c;那么就可以通過反射機制來獲得類的所有屬性和方法。反射有什么作用在運行時判斷任…

【轉載】移動端布局概念總結

布局準備工作及布局思想及概念: 一個顯示器&#xff08;pc端顯示器 及 手機屏顯示器&#xff09;&#xff0c;既有物理像素&#xff0c;又有獨立像素&#xff08;獨立像素也叫作css像素&#xff0c;用于前端人員使用&#xff09;&#xff1b; -->重要 首先確定設計稿的尺寸…

深入淺出:HTTP/2

上篇文章深入淺出&#xff1a;5G和HTTP里給自己挖了一根深坑&#xff0c;說是要寫一篇關于HTTP/2的文章&#xff0c;今天來還賬了。 本文分為以下幾個部分&#xff1a; HTTP/2的背景HTTP/2的特點HTTP/2的協議分析HTTP/2的支持 HTTP/2簡介 HTTP/2主要是為了解決現HTTP 1.1性能不…

畫了個Android

畫了個Android 今晚瞎折騰&#xff0c;閑著沒事畫了個機器人——android&#xff0c;浪費了一個晚上的時間。畫這丫還真不容易&#xff0c;為那些坐標&#xff0c;差點砸了鍵盤&#xff0c;好在最后畫出個有模有樣的&#xff0c;心稍安。 下面來看看畫這么個機器人需要些什么東…

數據治理 主數據 元數據_我們對數據治理的誤解

數據治理 主數據 元數據Data governance is top of mind for many of my customers, particularly in light of GDPR, CCPA, COVID-19, and any number of other acronyms that speak to the increasing importance of data management when it comes to protecting user data.…

mysql 選擇前4個_mysql從4個表中選擇

不要認為GROUP BY是必需的 . 雖然如果一個孩子有2個父記錄&#xff0c;你可能想用它來將2個父母分組到一行 - 但不確定這是否是你的要求 . 因為如果一個孩子有2個父母&#xff0c;那么將為該孩子返回的父母是未定義的 .假設所有孩子都有父母&#xff0c;所有父母都會有姓&#…

提高機器學習質量的想法_如何提高機器學習的數據質量?

提高機器學習質量的想法The ultimate goal of every data scientist or Machine Learning evangelist is to create a better model with higher predictive accuracy. However, in the pursuit of fine-tuning hyperparameters or improving modeling algorithms, data might …

mysql 集群實踐_MySQL Cluster集群探索與實踐

MySQL集群是一種在無共享架構(SNA&#xff0c;Share Nothing Architecture)系統里應用內存數據庫集群的技術。這種無共享的架構可以使得系統使用低廉的硬件獲取高的可擴展性。MySQL集群是一種分布式設計&#xff0c;目標是要達到沒有任何單點故障點。因此&#xff0c;任何組成部…

Python基礎:搭建開發環境(1)

1.Python語言簡介 2.Python環境 Python環境產品存在多個。 2.1 CPython CPython是Python官方提供的。一般情況下提到的Python就是指CPython&#xff0c;CPython是基于C語言編寫的。 CPython實現的解釋器將源代碼編譯為字節碼&#xff08;ByteCode&#xff09;&#xff0c;再由虛…

python數據結構之隊列(一)

隊列概念隊列&#xff08;queue&#xff09;是只允許在一端進行插入操作&#xff0c;而在另一端進行刪除操作的線性表。隊列是一種先進先出的&#xff08;First In First Out&#xff09;的線性表&#xff0c;簡稱FIFO。允許插入的一端為隊尾&#xff0c;允許刪除的一端為隊頭。…

Android實現圖片放大縮小

Android實現圖片放大縮小 package com.min.Test_Gallery; import Android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.Matrix; import android.os.Bun…

matlab散點圖折線圖_什么是散點圖以及何時使用

matlab散點圖折線圖When you were learning algebra back in high school, you might not have realized that one day you would need to create a scatter plot to demonstrate real-world results.當您在高中學習代數時&#xff0c;您可能沒有意識到有一天需要創建一個散點圖…

java判斷題_【Java判斷題】請大神們進來看下、這些判斷題你都知道多少~

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓、判斷改錯題(每題2分&#xff0c;共20分)(正確的打√&#xff0c;錯誤的打并說明原因)1、 Java系統包提供了很多預定義類,我們可以直接引用它們而不必從頭開始編寫程序。 ( )2、 程序可以用字符‘*’替代一個TextField中的每個字…

PoPo數據可視化第8期

PoPo數據可視化 聚焦于Web數據可視化與可視化交互領域&#xff0c;發現可視化領域有意思的內容。不想錯過可視化領域的精彩內容, 就快快關注我們吧 :) 微信訂閱號&#xff1a;popodv_com谷歌決定關閉云可視化服務 Fusion Tables谷歌宣布即將關閉其 Fusion Tables 云服務&#x…