欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一篇文章徹底搞懂面試中常被問(wèn)的各種“鎖”

 更新時(shí)間:2019年05月07日 10:13:34   作者:深夜里的程序猿  
這篇文章主要給大家介紹了關(guān)于面試中常被問(wèn)的各種“鎖”的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

鎖,顧名思義就是鎖住一些資源,當(dāng)只有我們拿到鑰匙的時(shí)候,才能操作鎖住的資源。在我們的Java,數(shù)據(jù)庫(kù),還有一些分布式的環(huán)境中,總是充斥著各種各樣的鎖讓人頭疼,例如“公平鎖”、“自旋鎖”、“讀寫(xiě)鎖”、“分布式鎖”等等。

其實(shí)真實(shí)的情況是,鎖并沒(méi)有那么多,很多概念只是從不同的功能特性,設(shè)計(jì),以及鎖的狀態(tài)這些不同的側(cè)重點(diǎn)來(lái)說(shuō)明的,因此我們可以根據(jù)不同的分類(lèi)來(lái)搞明白為什么會(huì)有這些“鎖”?坐穩(wěn)扶好了,準(zhǔn)備開(kāi)車(chē)。

正文

“公平鎖”與“非公平鎖”

  • 公平鎖:指線程在等待獲取同一個(gè)鎖的時(shí)候,是嚴(yán)格按照申請(qǐng)鎖的時(shí)間順序來(lái)進(jìn)行的,這就意味著在程序正常運(yùn)作的時(shí)候,不會(huì)有線程執(zhí)行不到,而被“餓死”,但是也需要額外的機(jī)制來(lái)維護(hù)這種順序,所以效率相對(duì)于非公平鎖會(huì)差點(diǎn)。
  • 非公平鎖:概念跟“公平鎖”恰恰相反,隨機(jī)線程獲取鎖,相率相對(duì)高。
new ReentrantLock(); //默認(rèn)非公平鎖
new ReentrantLock(true); //公平鎖

“重入鎖(遞歸鎖)”與“不可重入鎖(自旋鎖)”

這里要注意了,重入/遞歸,不可重入/自旋,雖然名字不同,但是確實(shí)是同一種鎖,只是從鎖的表現(xiàn)跟實(shí)現(xiàn)方式的角度來(lái)命名而已。

重入鎖:當(dāng)一個(gè)線程獲取了A鎖以后,若后續(xù)方法運(yùn)行被A鎖鎖住的話,當(dāng)前線程也是可以直接進(jìn)入的。

public class Demo {
 private Lock lockA;
 
 public Demo(Lock Lock) {
  this.lockA = lock;
 }
 
 public void methodA() {
  lockA.lock();
  methodB();
  lockA.unlock();
 }
 
 public void methodB() {
  lockA.lock();
  //dosm
  lockA.unlock();
 }
 }

當(dāng)我們運(yùn)行methodA()的時(shí)候,線程獲取了lockA,然后調(diào)用methodB()的時(shí)候發(fā)現(xiàn)也需要lockA,由于這是一個(gè)可重入鎖,所以當(dāng)前線程也是可以直接進(jìn)入的。在java中,synchronized跟ReetrantLock都是可重入鎖。 

不可重入鎖:以上面的代碼實(shí)例來(lái)說(shuō)明,就是methodA進(jìn)入methodB的時(shí)候不能直接獲取鎖,必須先調(diào)用unLock釋放鎖。才能執(zhí)行下去,那實(shí)現(xiàn)不可重入鎖有什么方式呢?那就是自旋,所以會(huì)有一個(gè)小名叫做自旋鎖。

public class SpinLock {

 private AtomicReference<Thread> sign =new AtomicReference<>();

 public void lock(){
  Thread current = Thread.currentThread();
  while(!sign .compareAndSet(null, current)){
  }
 }

 public void unlock (){
  Thread current = Thread.currentThread();
  sign .compareAndSet(current, null);
 }
}

 “悲觀鎖”與“樂(lè)觀鎖”

這兩種鎖呢,其實(shí)是一個(gè)很宏觀的分類(lèi),它不是一種具體的鎖,而是泛指看待并發(fā)的程度。

悲觀鎖:有一個(gè)“悲觀”的心態(tài),既每次取數(shù)據(jù)的時(shí)候,都會(huì)認(rèn)為該數(shù)據(jù)會(huì)被修改,所以必須加一把鎖才安心。

樂(lè)觀鎖:樂(lè)觀的孩子,認(rèn)為同一個(gè)數(shù)據(jù)不會(huì)發(fā)生并發(fā)操作的行為,所以取的時(shí)候不會(huì)加鎖,只有在更新的時(shí)候,會(huì)通過(guò)例如版本號(hào)之類(lèi)的來(lái)判斷是否數(shù)據(jù)被修改了。

Java中各種鎖其實(shí)都是悲觀鎖的實(shí)現(xiàn),既操作的數(shù)據(jù)的都會(huì)被獲取鎖的線程鎖住,而樂(lè)觀鎖的話,一般是通過(guò)cas(compare and swap)的思想來(lái)實(shí)現(xiàn),例如一些原子類(lèi)AtomicInteger使用自旋來(lái)原子更新。

“共享鎖”與“排他鎖”

這兩種鎖的概念比較多的出現(xiàn)在數(shù)據(jù)庫(kù)的事務(wù)當(dāng)中。

共享鎖:也稱(chēng)讀鎖或S鎖。如果事務(wù)對(duì)數(shù)據(jù)A加上共享鎖后,則其他事務(wù)只能對(duì)A再加共享鎖,不能加排它鎖。獲準(zhǔn)共享鎖的事務(wù)只能讀數(shù)據(jù),不能修改數(shù)據(jù)。在java中的ReetrantReadWriteLock()也是如此。

排它鎖:也稱(chēng)獨(dú)占鎖、寫(xiě)鎖或X鎖。如果事務(wù)對(duì)數(shù)據(jù)A加上排它鎖后,則其他事務(wù)不能再對(duì)A加任何類(lèi)型的鎖。獲得排它鎖的事務(wù)即能讀數(shù)據(jù)又能修改數(shù)據(jù)。

分布式鎖

我們上面聊的這些鎖,都是在單個(gè)程序上面的不同線程之間來(lái)實(shí)現(xiàn)的,那么當(dāng)我們的不同程序需要去競(jìng)爭(zhēng)同一塊資源的時(shí)候,這就需要分布式鎖了,我們可以通過(guò)redis、zookeeper等中間件來(lái)實(shí)現(xiàn)分布式鎖。

 對(duì)于鎖來(lái)說(shuō),其實(shí)還有偏向鎖,輕量級(jí)鎖等,但是這里涉及到的內(nèi)容就比較多,這里就不在展開(kāi)篇幅介紹了,有興趣的同學(xué)可自行研究,如果你能搞懂上面介紹的這些鎖,那基本上在絕大部分的公司關(guān)于“鎖”的問(wèn)題都可以迎刃而解。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • java中的定時(shí)器和多線程

    java中的定時(shí)器和多線程

    這篇文章主要介紹了java中的定時(shí)器和多線程用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java控制臺(tái)輸入數(shù)組并逆序輸出的方法實(shí)例

    Java控制臺(tái)輸入數(shù)組并逆序輸出的方法實(shí)例

    這篇文章主要介紹了Java手動(dòng)輸入數(shù)組并逆向輸出的方法實(shí)例,需要的朋友可以參考下。
    2017-08-08
  • kotlin之閉包案例詳解

    kotlin之閉包案例詳解

    這篇文章主要介紹了kotlin之閉包案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • Java并發(fā)編程之同步容器

    Java并發(fā)編程之同步容器

    這篇文章主要介紹了Java并發(fā)編程之同步容器,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-05-05
  • SpringCloud網(wǎng)關(guān)(Zuul)如何給多個(gè)微服務(wù)之間傳遞共享參數(shù)

    SpringCloud網(wǎng)關(guān)(Zuul)如何給多個(gè)微服務(wù)之間傳遞共享參數(shù)

    這篇文章主要介紹了SpringCloud網(wǎng)關(guān)(Zuul)如何給多個(gè)微服務(wù)之間傳遞共享參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Spring Boot+Mybatis+Pagehelper分頁(yè)實(shí)現(xiàn)

    Spring Boot+Mybatis+Pagehelper分頁(yè)實(shí)現(xiàn)

    本篇文章主要講述的是Spring Boot+Mybatis+Pagehelper分頁(yè)實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 使用SpringAOP獲取用戶(hù)操作日志入庫(kù)

    使用SpringAOP獲取用戶(hù)操作日志入庫(kù)

    這篇文章主要介紹了使用SpringAOP獲取用戶(hù)操作日志入庫(kù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java關(guān)于String.split("|")的使用方式

    java關(guān)于String.split("|")的使用方式

    這篇文章主要介紹了java關(guān)于String.split("|")的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Mybatis配置錯(cuò)誤:java.lang.ExceptionInInitializerError

    Mybatis配置錯(cuò)誤:java.lang.ExceptionInInitializerError

    這篇文章主要介紹了Mybatis配置錯(cuò)誤:java.lang.ExceptionInInitializerError的相關(guān)資料,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Java?ASM使用logback日志級(jí)別動(dòng)態(tài)切換方案展示

    Java?ASM使用logback日志級(jí)別動(dòng)態(tài)切換方案展示

    這篇文章主要介紹了Java?ASM使用logback日志級(jí)別動(dòng)態(tài)切換方案展示,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04

最新評(píng)論