<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                **公平鎖和非公平鎖:** 公平鎖是隊列的,按順序,非公平鎖搶到就占用鎖,可插隊。非公平鎖吞吐量比公平鎖大,但是可能會出現饑餓想象(某個線程一直都拿不到鎖) synchronized 和 ReentrantLock 默認都是非公平鎖 **可重入鎖(遞歸鎖)** 訪問的同步代碼中還有同步代碼,這時候內層的代碼塊可直接進入,使用的和外層是同一把鎖。synchronized 和 ReentrantLock 是可重入鎖。可防止死鎖 **自旋鎖:** 采用循環的方式去嘗試獲取鎖(CAS)。優點 不會立即阻塞而且減少線程上下文切換的消耗 缺點 循環會消耗CPU,如果一直失敗,對CPU影響大 **獨占鎖(寫鎖) / 共享鎖(讀鎖)** 有一個線程在寫,別的線程就沒法讀或寫 **偏向鎖** 無競爭時使用,一旦有第二個線程競爭,就會從偏向鎖改成輕量級鎖 ## 1. CAS 原理? 輕量級自旋鎖 線程拿到的值和主內存中的值一致, 就將要寫入的值寫入到主內存,否則就修改失敗。 使用 Java中的sun.misc.Unsafe 類 這個類的方法都是native的,完全依賴于硬件的功能,通過它實現了原子操作。CAS是一條CPU的原子指令,執行是連續的,執行過程中不允許被打斷,不會造成數據不一致問題。 ## 2. CAS 缺點? 1. 循環時間長開銷會很大 1. 如果CAS失敗,會一直進行嘗試自旋(do while 方式),如果長時間不成功,會一直循環,對cpu影響大。 ## 3. ABA問題 1. 簡單來說就是 最初拿到的值和最終比較時值一樣,但是這期間值實際是修改過的。 T1 T2 倆個線程從主內存中都拿到的變量是A,T1比較慢,T2 把A改成了B,并寫入到主內存,又來了個T3,拿到主內存 B并改成A寫入到主內存,這時候T1執行完成值改為了1,發現主內存還是A和自己當時拿到的值一致,就將1寫入主內存成功。但是實際上主內存的值已經從出現過A=》B=》A的過程。就是一個線程往主內存寫入數據時,發現主內存中的值和線程當時拿到的值是相同的,符合CAS的邏輯,但是實際上主內存中的這個值已經修改過多次,只能當這個線程去寫入時,剛好和線程當時拿到的值一致。中間過程中值可能已經被改動過了。 ## 3. ABA 解決方式? 版本號,修改一次版本號就增加一次。比如 elasticsearch 中數據每更新一次,版本號字段就加一 ## 4. 什么是偏向鎖? 在對象頭中記錄線程id,如果下次來的還是這個線程則直接運行后續代碼。 需要啟用,JVM 默認延遲 4s 自動啟用 ## 5. 什么是synchronized ? 是Java中的關鍵字:用來修飾方法、對象實例。屬于獨占鎖、悲觀鎖、可重入鎖、非公平鎖。 1. 作用于實例方法時,鎖住的是對象的實例(this); 2. 當作用于靜態方法時,鎖住的是 Class類,相當于類的一個全局鎖, 會鎖所有調用該方法的線程; 3. synchronized 作用于一個非 NULL的對象實例時,鎖住的是所有以該對象為鎖的代碼塊。它有多個隊列,當多個線程一起訪問某個對象監視器的時候,對象監視器會將這些線程存儲在不同的容器中。 ## 6. synchronized 加鎖原理? jdk 1.6 之前直接就是重量級鎖:通過對象內部的監視器(monitor)實現,依賴于操作系統,線程需要爭搶 monitor,搶到的就是加鎖成功,沒搶到的會放到隊列中。涉及到阻塞同步,上下文切換,線程調度,操作系統的內核態和用戶態的切換。消耗大,性能差。 jdk1.6 以后對synchronized鎖進行了優化 內核態:當進程(線程)需要內核代碼執行時,就是處于內核態。其他都是用戶態。 ## 7. synchronized 鎖升級(鎖膨脹)? 無鎖 => 偏向鎖 =》 自旋鎖(輕量級鎖) =》 重量級鎖 當有線程加鎖時,會在對象頭中記錄線程id,如果以后還是這個線程,則可以直接運行后續代碼,當2個線程以上爭搶加鎖時,則直接升級為輕量級鎖,CAS進行自旋加鎖,當線程加鎖競爭激烈,CAS自旋不成功(默認 10 次)則升級為重量級鎖。 ## 可重入鎖如果加了兩把,但是只釋放了一把會出現什么問題? 程序卡死,線程不能出來,也就是說我們申請了幾把鎖,就需要釋放幾把鎖。 ## 如果只加了一把鎖,釋放兩次會出現什么問題? 會報錯,java.lang.IllegalMonitorStateException。 ## Lock和synchronized的區別? 1. Lock 需要手動獲取鎖和釋放鎖 2. Lock 是一個接口,而 synchronized 是 Java 中的關鍵字, synchronized 是內置的語言實現。 3. Lock 可以讓等待鎖的線程響應中斷,而 synchronized 卻不行,使用 synchronized 時,等待的線程會一直等待下去,不能夠響應中斷。 4. Lock 可以讓等待鎖的線程響應中斷,而 synchronized 卻不行,使用 synchronized 時,等待的線程會一直等待下去,不能夠響應中斷。 5. Lock 可以讓等待鎖的線程響應中斷,而 synchronized 卻不行,使用 synchronized 時,等待的線程會一直等待下去,不能夠響應中斷。 6. synchronized 在發生異常時,會自動釋放線程占有的鎖,因此不會導致死鎖現象發生;而 Lock 在發生異常時,如果沒有主動通過 unLock()去釋放鎖,則很可能造成死鎖現象,因此使用 Lock 時需要在 finally 塊中釋放鎖。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看