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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

可重入锁和不可重入锁

發(fā)布時(shí)間:2025/3/16 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 可重入锁和不可重入锁 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)自https://www.cnblogs.com/dj3839/p/6580765.html

鎖的簡(jiǎn)單應(yīng)用


用lock來保證原子性(this.count++這段代碼稱為臨界區(qū))

什么是原子性,就是不可分,從頭執(zhí)行到尾,不能被其他線程同時(shí)執(zhí)行。

可通過CAS來實(shí)現(xiàn)原子操作

CAS(Compare and Swap):

CAS操作需要輸入兩個(gè)數(shù)值,一個(gè)舊值(期望操作前的值)和一個(gè)新值,在操作期間先比較下舊值有沒有發(fā)生變化,如果沒有發(fā)生變化,才交換成新值,發(fā)生了變化則不交換。

CAS主要通過compareAndSwapXXX()方法來實(shí)現(xiàn),而這個(gè)方法的實(shí)現(xiàn)需要涉及底層的unsafe類

unsafe類:java不能直接訪問操作系統(tǒng)底層,而是通過本地方法來訪問。Unsafe類提供了硬件級(jí)別的原子操作

這里有個(gè)介紹原子操作的博客

https://my.oschina.net/xinxingegeya/blog/499223

還有對(duì)unsafe類詳解的博客

http://www.cnblogs.com/mickole/articles/3757278.html

?

1 public class Counter{2 private Lock lock = new Lock();3 private int count = 0;4 public int inc(){5 lock.lock();6 this.count++;7 lock.unlock();8 return count;9 } 10 }

不可重入鎖


先來設(shè)計(jì)一種鎖

1 public class Lock{2 private boolean isLocked = false;3 public synchronized void lock() throws InterruptedException{4 while(isLocked){ 5 wait();6 }7 isLocked = true;8 }9 public synchronized void unlock(){ 10 isLocked = false; 11 notify(); 12 } 13 }

這其實(shí)是個(gè)不可重入鎖,舉個(gè)例子

1 public class Count{2 Lock lock = new Lock();3 public void print(){4 lock.lock();5 doAdd();6 lock.unlock();7 }8 public void doAdd(){9 lock.lock(); 10 //do something 11 lock.unlock(); 12 } 13 }

當(dāng)調(diào)用print()方法時(shí),獲得了鎖,這時(shí)就無法再調(diào)用doAdd()方法,這時(shí)必須先釋放鎖才能調(diào)用,所以稱這種鎖為不可重入鎖,也叫自旋鎖。

可重入鎖


設(shè)計(jì)如下:

1 public class Lock{2 boolean isLocked = false;3 Thread lockedBy = null;4 int lockedCount = 0;5 public synchronized void lock()6 throws InterruptedException{7 Thread thread = Thread.currentThread();8 while(isLocked && lockedBy != thread){9 wait(); 10 } 11 isLocked = true; 12 lockedCount++; 13 lockedBy = thread; 14 } 15 public synchronized void unlock(){ 16 if(Thread.currentThread() == this.lockedBy){ 17 lockedCount--; 18 if(lockedCount == 0){ 19 isLocked = false; 20 notify(); 21 } 22 } 23 } 24 }

相對(duì)來說,可重入就意味著:線程可以進(jìn)入任何一個(gè)它已經(jīng)擁有的鎖所同步著的代碼塊。

第一個(gè)線程執(zhí)行print()方法,得到了鎖,使lockedBy等于當(dāng)前線程,也就是說,執(zhí)行的這個(gè)方法的線程獲得了這個(gè)鎖,執(zhí)行add()方法時(shí),同樣要先獲得鎖,因不滿足while循環(huán)的條件,也就是不等待,繼續(xù)進(jìn)行,將此時(shí)的lockedCount變量,也就是當(dāng)前獲得鎖的數(shù)量加一,當(dāng)釋放了所有的鎖,才執(zhí)行notify()。如果在執(zhí)行這個(gè)方法時(shí),有第二個(gè)線程想要執(zhí)行這個(gè)方法,因?yàn)閘ockedBy不等于第二個(gè)線程,導(dǎo)致這個(gè)線程進(jìn)入了循環(huán),也就是等待,不斷執(zhí)行wait()方法。只有當(dāng)?shù)谝粋€(gè)線程釋放了所有的鎖,執(zhí)行了notify()方法,第二個(gè)線程才得以跳出循環(huán),繼續(xù)執(zhí)行。

這就是可重入鎖的特點(diǎn)。

java中常用的可重入鎖

synchronized

java.util.concurrent.locks.ReentrantLock

ps:順便記錄下java中實(shí)現(xiàn)原子操作的類(記錄至http://blog.csdn.net/huzhigenlaohu/article/details/51646455)

  • AtomicIntegerFieldUpdater:原子更新整型的字段的更新器
  • AtomicLongFieldUpdater:原子更新長(zhǎng)整型字段的更新器
  • AtomicStampedReference:原子更新帶有版本號(hào)的引用類型。該類將整型數(shù)值與引用關(guān)聯(lián)起來,可用于原子的更新數(shù)據(jù)和數(shù)據(jù)的版本號(hào),可以解決使用CAS進(jìn)行原子更新時(shí)可能出現(xiàn)的ABA問題。
  • AtomicReference :原子更新引用類型
  • AtomicReferenceFieldUpdater :原子更新引用類型里的字段
  • AtomicMarkableReference:原子更新帶有標(biāo)記位的引用類型。可以原子更新一個(gè)布爾類型的標(biāo)記位和應(yīng)用類型
  • AtomicIntegerArray :原子更新整型數(shù)組里的元素
  • AtomicLongArray :原子更新長(zhǎng)整型數(shù)組里的元素
  • AtomicReferenceArray : 原子更新引用類型數(shù)組的元素
  • AtomicBooleanArray :原子更新布爾類型數(shù)組的元素
  • AtomicBoolean :原子更新布爾類型
  • AtomicInteger: 原子更新整型
  • AtomicLong: 原子更新長(zhǎng)整型

?

轉(zhuǎn)載于:https://www.cnblogs.com/ffaiss/p/11132984.html

總結(jié)

以上是生活随笔為你收集整理的可重入锁和不可重入锁的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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