亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

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

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

                前言

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

                相信很多同學對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),每次釋放鎖和獲取鎖都會導致用戶態(tài)和內(nèi)核態(tài)的切換,從而增加系統(tǒng)性能的開銷,當出現(xiàn)大并發(fā)的情況下,鎖競爭會比較激烈,性能顯得非常糟糕,所以稱為重量級鎖,所以大家往往會選擇Lock鎖。

                鎖優(yōu)化

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

                synchronized 實現(xiàn)原理

                我們了解鎖優(yōu)化之前,我們先看一下它的實現(xià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

                我們重點關注monitorenter和monitorexit,那么他倆是什么意思呢

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

                monitorexit,執(zhí)行 monitorexit 的線程必須是 monitor 的擁有者,指令執(zhí)行后,monitor 的進入數(shù)減 1,如果減 1 后進入數(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;}

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

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

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

                Synchronized中的鎖優(yōu)化

                自適應自旋鎖

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

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

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

                鎖消除

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

                鎖粗化

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

                偏向鎖

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

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

                輕量級鎖

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

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

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

                重量級鎖

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

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

                結(jié)束語

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

                往期內(nèi)容推薦

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

                項目源碼(源碼已更新 歡迎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系列教程合集
                • 一起來學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

                相關推薦

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                  2022年11月25日

                聯(lián)系我們

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