在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

    面試官:有了解過Synchronized嗎 說說看

    面試官: 有了解過Synchronized嗎 說說看

    前言

    目前正在出一個Java多線程專題長期系列教程,從入門到進(jìn)階源碼解讀, 篇幅會較多, 喜歡的話,給個關(guān)注 ~ 本篇內(nèi)容純理論一點(diǎn)

    相信很多同學(xué)對synchronized的使用上不陌生,之前也給大家講解過它的使用。本篇主要帶大家深入了解一下它,大家也可以自己試著總結(jié)一下,這也是面試中常常問到的,單純的回答它的基本使用,是驚艷不到面試官的~

    synchronized 介紹

    從字面意思翻譯過來就是同步的意思,所以它也叫同步鎖,我們通常會給某個方法或者某塊代碼加上Synchronized鎖來解決多線程中并發(fā)帶來的問題,它也是最常用,最簡單的一種方法

    在Java中,鎖基本上都是基于對象而言的,所以又稱為對象鎖, 一個類通常只有一個class對象和n個實例對象,它們共享class對象,而我們有時候會對class對象加鎖,所以又稱為class對象鎖

    這里大家要注意的是對象需要是一個非null的對象,我們通常也叫做對象監(jiān)視器(Object Monitor)

    重量級鎖

    在JDK 1.5之前,它是一個重量級鎖,我們通常都會使用它來保證線程同步。在1.5的時候還提供了一個Lock接口來實現(xiàn)同步鎖的功能,我們只需要顯式的獲取鎖和釋放鎖。

    重在哪

    在1.5的時候,Synchronized它依賴于操作系統(tǒng)底層的Mutex Lock實現(xiàn),每次釋放鎖和獲取鎖都會導(dǎo)致用戶態(tài)和內(nèi)核態(tài)的切換,從而增加系統(tǒng)性能的開銷,當(dāng)出現(xiàn)大并發(fā)的情況下,鎖競爭會比較激烈,性能顯得非常糟糕,所以稱為重量級鎖,所以大家往往會選擇Lock鎖。

    鎖優(yōu)化

    但是Synchronized又是那么的簡單好用,又是官方自帶的,怎么可能放棄呢?所以在1.6之后,引入了大量的鎖優(yōu)化,比如自旋鎖,輕量級鎖, 偏向鎖等,下面我們逐個看一下~

    synchronized 實現(xiàn)原理

    我們了解鎖優(yōu)化之前,我們先看一下它的實現(xiàn)原理。

    首先我們看下同步塊中,因為它是關(guān)鍵字,我們看不到源碼實現(xiàn),所以只能反編譯看一下,通過 javap -v **.class

    public static void main(String[] args) { synchronized(Demo.class) { System.out.println(“hello”); } }public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=3, args_size=1 0: ldc #2 // class com/thread/base/Demo 2: dup 3: astore_1 4: monitorenter 5: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 8: ldc #4 // String hello 10: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 13: aload_1 14: monitorexit 15: goto 23 18: astore_2 19: aload_1 20: monitorexit 21: aload_2 22: athrow 23: return

    我們重點(diǎn)關(guān)注monitorenter和monitorexit,那么他倆是什么意思呢

    monitorenter,如果當(dāng)前 monitor 的進(jìn)入數(shù)為 0 時,線程就會進(jìn)入 monitor,并且把進(jìn)入數(shù) + 1,那么該線程就是 monitor 的擁有者 (owner)。如果該線程已經(jīng)是 monitor 的擁有者,又重新進(jìn)入,就會把進(jìn)入數(shù)再次 + 1。也就是可重入。

    monitorexit,執(zhí)行 monitorexit 的線程必須是 monitor 的擁有者,指令執(zhí)行后,monitor 的進(jìn)入數(shù)減 1,如果減 1 后進(jìn)入數(shù)為 0,則該線程會退出 monitor。其他被阻塞的線程就可以嘗試去獲取 monitor 的所有權(quán)。指令出現(xiàn)了兩次,第 1 次為同步正常退出釋放鎖;第2次為發(fā)生異步退出釋放鎖;

    我們再來看一下, 修飾實例方法中的表現(xiàn):

    class Demo { public synchronized void hello() { System.out.println(“hello”); }} public synchronized void hello(); descriptor: ()V flags: ACC_PUBLIC, ACC_SYNCHRONIZED Code: stack=2, locals=1, args_size=1 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3 // String hello 5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: return LineNumberTable: line 25: 0 line 26: 8 LocalVariableTable: Start Length Slot Name Signature 0 9 0 this Lcom/thread/base/Demo;}

    我們重點(diǎn)關(guān)注ACC_SYNCHRONIZED,它作用就是一旦執(zhí)行到這個方法時,就會先判斷是否有標(biāo)志位,如果有,就會先嘗試獲取 monitor,獲取成功才能執(zhí)行方法,方法執(zhí)行完成后再釋放 monitor。在方法執(zhí)行期間,其他線程都無法獲取同一個 monitor。歸根結(jié)底還是對 monitor 對象的爭奪,只是同步方法是一種隱式的方式來實現(xiàn)。

    synchronized 在 JVM 里的實現(xiàn)就是基于進(jìn)入和退出 monitor 來實現(xiàn)的,底層則是通過成對的 MonitorEnter 和 MonitorExit 指令來實現(xiàn)

    有了以上的認(rèn)識,下面我們就看看鎖優(yōu)化

    Synchronized中的鎖優(yōu)化

    自適應(yīng)自旋鎖

    自旋鎖,之前我們講FutureTask源碼的時候,有一個內(nèi)部方法awaitDone(),給大家有介紹過,就是基于它實現(xiàn)的,今天再給大家總結(jié)一下。

    它的目的是為了避免阻塞和喚醒的切換,在沒有獲得鎖的時候就不進(jìn)入阻塞,不斷地循環(huán)檢測鎖是否被釋放。但是,它也有弊端,我們通常來講,一個線程占用鎖的時間相對較短,但是萬一占用很長時間怎么辦?這樣會占用大量cpu時間,這樣會導(dǎo)致性能變差,所以在1.6引入了自適應(yīng)自旋鎖來滿足這樣的場景。

    那么什么是自適應(yīng)自旋鎖呢 自旋的次數(shù)不是固定的,而是由前一次在同一個鎖上的自旋時間及鎖的擁有者的狀態(tài)來決定。如果此次自旋成功了,很有可能下一次也能成功,于是允許自旋的次數(shù)就會更多,反過來說,如果很少有線程能夠自旋成功,很有可能下一次也是失敗,則自旋次數(shù)就更少。這樣一來,就能夠更好的利用系統(tǒng)資源。

    鎖消除

    鎖消除是一種鎖的優(yōu)化策略,這種優(yōu)化更加徹底,在 JVM 編譯時,通過對運(yùn)行上下文的掃描,去除不可能存在共享資源競爭的鎖。這種優(yōu)化策略可以消除沒有必要的鎖,去除獲取鎖的時間。

    鎖粗化

    如果一系列的連續(xù)加鎖解鎖操作,可能會導(dǎo)致不必要的性能損耗,所以引入鎖粗話的概念。意思是將多個連續(xù)加鎖、解鎖的操作連接在一起,擴(kuò)展成為一個范圍更大的鎖, 這個應(yīng)該很好理解

    偏向鎖

    偏向鎖是JDK 1.6引入的,它解決的場景是什么呢 我們大部分使用鎖都是解決多線程場景下的問題,但有時候往往一個線程也會存在這樣的問題,偏向鎖是在單線程執(zhí)行代碼塊時使用的機(jī)制。

    鎖的爭奪實際上是 Monitor 對象的爭奪,還有每個對象都有一個對象頭,對象頭是由 Mark Word 和 Klass pointer 組成的。一旦有線程持有了這個鎖對象,標(biāo)志位修改為 1,就進(jìn)入偏向模式,同時會把這個線程的 ID 記錄在對象的 Mark Word 中,當(dāng)同一個線程再次進(jìn)入時,就不再進(jìn)行同步操作,大大減少了鎖獲取的時間,從而提高了性能。

    輕量級鎖

    我們上邊提到的偏向鎖,在多線程情況下如果偏向鎖失敗就會升級為輕量級鎖, Mark Word 的結(jié)構(gòu)也變?yōu)檩p量級鎖的結(jié)構(gòu)。

    執(zhí)行同步代碼塊之前,JVM 會在線程的棧幀中創(chuàng)建一個鎖記錄(Lock Record),并將 Mark Word 拷貝復(fù)制到鎖記錄中。然后嘗試通過 CAS 操作將 Mark Word 中的鎖記錄的指針,指向創(chuàng)建的 Lock Record。如果成功表示獲取鎖狀態(tài)成功,如果失敗,則進(jìn)入自旋獲取鎖狀態(tài)。

    如果自旋鎖失敗,就會升級為重量級鎖,也就是我們之前講的,會把線程阻塞,需等待喚醒。

    重量級鎖

    它又稱為悲觀鎖, 升級到這種情況下,鎖競爭比較激烈,占用時間也比較長,為了減少cpu的消耗,會將線程阻塞,進(jìn)入阻塞隊列。

    synchronized就是通過鎖升級策略來適應(yīng)不同的場景,所以現(xiàn)在synchronized被優(yōu)化的很好,也是我們項目中往往都會使用它的理由。

    結(jié)束語

    本節(jié)的內(nèi)容比較多,大家好好理解,特別是鎖的升級策略。本節(jié)我們提到了Lock鎖,下一節(jié),帶大家深入學(xué)習(xí)一下Java的Lock ~

    往期內(nèi)容推薦

    • Java多線程專題之線程與進(jìn)程概述
    • Java多線程專題之線程類和接口入門
    • Java多線程專題之進(jìn)階學(xué)習(xí)Thread(含源碼分析)
    • Java多線程專題之Callable、Future與FutureTask(含源碼分析)
    • 面試官: 有了解過線程組和線程優(yōu)先級嗎
    • 面試官: 說一下線程的生命周期過程
    • 面試官: 說一下線程間的通信
    • 面試官: 說一下Java的共享內(nèi)存模型
    • 面試官: 有了解過指令重排嗎,什么是happens-before
    • 面試官: 有了解過volatile關(guān)鍵字嗎 說說看
    • 我的博客(閱讀體驗較佳)
    • 寫給初學(xué)者的Java基礎(chǔ)教程
    • 一文帶你快速學(xué)習(xí)Java集合類
    • 花幾分鐘快速了解一下泛型與枚舉
    • Java注解與反射入門到進(jìn)階
    • JavaIO教程從入門到進(jìn)階

    項目源碼(源碼已更新 歡迎star )

    • java-thread-all
    • 地址: https://github.com/qiuChengleiy/java-thread-all.git

    推薦 SpringBoot & SpringCloud (源碼已更新 歡迎star )

    • springboot-all
    • 地址: https://github.com/qiuChengleiy/springboot-all.git
    • SpringBoot系列教程合集
    • 一起來學(xué)SpringCloud合集
    鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
    用戶投稿
    上一篇 2022年6月12日 18:15
    下一篇 2022年6月12日 18:15

    相關(guān)推薦

    • 分享4條發(fā)微商朋友圈的方法(微商朋友圈應(yīng)該怎么發(fā))

      對于微商朋友來說,朋友圈的重要性不言而喻了。 那么微商的朋友圈到底該怎么發(fā)呢? 為什么同樣是經(jīng)營一個朋友圈,有的微商看起來逼格滿滿,實際效果也不錯;而有的卻動都不動就被屏蔽甚至拉黑…

      2022年11月27日
    • 《寶可夢朱紫》夢特性怎么獲得?隱藏特性獲取方法推薦

      寶可夢朱紫里有很多寶可夢都是擁有夢特性會變強(qiáng)的寶可夢,很多玩家不知道夢特性怎么獲得,下面就給大家?guī)韺毧蓧糁熳想[藏特性獲取方法推薦,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 …

      2022年11月25日
    • 《寶可夢朱紫》奇魯莉安怎么進(jìn)化?奇魯莉安進(jìn)化方法分享

      寶可夢朱紫中的奇魯莉安要怎么進(jìn)化呢?很多玩家都不知道,下面就給大家?guī)韺毧蓧糁熳掀骠斃虬策M(jìn)化方法分享,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 奇魯莉安進(jìn)化方法分享 奇魯莉安…

      2022年11月25日
    • 非匿名指令新手十連怎么選?非匿名指令新手無限十連選擇推薦

      非匿名指令新手十連怎么選?進(jìn)入游戲之后大家能得到一個新手無限十連,可以幫大家抽到滿意的角色,新手十連的選擇小編在下面也會有分享,不知道如何選擇的可以看看小編提供的攻略,了解新手十連…

      2022年11月25日
    • 5+3疫情防控從哪天開始算(遼寧疫情防控最新政策)

      最近有關(guān)國內(nèi)各地的疫情大家也都有在持續(xù)關(guān)注,目前國內(nèi)各地疫情隔離時間也根據(jù)二十條防控措施有了新的調(diào)整。那么,5+3疫情防控從哪天開始算?對于密接的5+3隔離時間計算大家還是比較關(guān)心…

      2022年11月25日
    • 2023年擺地攤賣什么最賺錢而且很受歡迎(2022年擺地攤合法嗎)

      關(guān)于擺地攤賺錢每年的熱度也是非常高的,很多想要做點(diǎn)小本生意的商家也都會選擇擺地攤這個項目,所需要的成本也是非常低的。那么,2023年擺地攤賣什么最賺錢而且很受歡迎?今天極客號小編整…

      2022年11月25日
    • 藍(lán)碼怎么變綠碼需要幾天(藍(lán)碼怎么變綠碼需要幾天)

      大家都知道健康碼的顏色有紅碼、綠碼、黃碼,近日湖南健康碼上線“藍(lán)碼”,不少小伙伴發(fā)現(xiàn)自己健康碼變藍(lán)了,都想趕緊恢復(fù)綠碼,那么藍(lán)碼怎么變綠碼需要幾天?下面小編為大家?guī)硭{(lán)碼變綠碼需要…

      2022年11月25日
    • 拼多多百億補(bǔ)貼預(yù)售一般多久發(fā)貨(拼多多百億補(bǔ)貼預(yù)售)

      拼多多里面有很多優(yōu)惠活動,其中百億補(bǔ)貼活動非?;鸨?,一些里面的東西價格比別的平臺便宜,質(zhì)量也有保障,還有預(yù)售的活動,那么拼多多百億補(bǔ)貼預(yù)售一般多久發(fā)貨?下面小編為大家?guī)砥炊喽喟賰|…

      2022年11月25日
    • 密接5+3是什么意思(密接人員是什么意思)

      如今新冠病例的傳播速度是越來越快了,對于感染了新冠病毒的人員來說都會采取隔離觀看措施。而據(jù)了解,當(dāng)前國內(nèi)又對新冠疫情防控政策做了新的調(diào)整優(yōu)化,其中密接管理調(diào)整為“5+3”。很多人對…

      2022年11月25日
    • 北京疫情多久能解除封控(北京疫情還要多久結(jié)束)

      最近一段時間北京疫情形勢備受關(guān)注,馬上就要到年底了,不少人想要去北京辦事,。都非常關(guān)注當(dāng)?shù)匾咔橄嚓P(guān)政策,那么 北京疫情多久能解除封控?北京疫情什么時候恢復(fù)正常生活?下面小編為大家?guī)А?/p>

      2022年11月25日

    聯(lián)系我們

    聯(lián)系郵箱:admin#wlmqw.com
    工作時間:周一至周五,10:30-18:30,節(jié)假日休息