<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      synchronized 鎖是可重入鎖嗎?如何驗證?

      摘要:舉例證明 synchronized鎖 是可重入鎖,并描述可重入鎖的實現原理。

      綜述

      ??先給大家一個結論:synchronized鎖 是可重入鎖

      ??關于什么是可重入鎖,通俗來說,當線程請求一個由其它線程持有的對象鎖時,該線程會阻塞,而當線程請求由自己持有的對象鎖時,如果該鎖是重入鎖,請求就會成功,否則阻塞。或者說,可重入鎖是同一個線程重復請求由自己持有的鎖對象時,可以請求成功而不會發生死鎖。與多線程并發執行的線程安全不同,可重入強調對單個線程執行時重新進入同一個子程序仍然是安全的。可重入鎖又稱遞歸鎖。

      驗證可重入

      ??假設我們現在不知道它是不是一個可重入鎖,那我們就應該想方設法來驗證它是不是可重入鎖?怎么驗證呢?看下面的代碼!

      public class SuperSalesman {
      
          public int ticketNum = 10;
      
          public synchronized void superSaleTickets()  {
              ticketNum --;
              System.out.println("父類售票后,剩余票數:" + ticketNum
                      + " " + Thread.currentThread().getName());
              try {
                  Thread.sleep(30);
              } catch (InterruptedException e) {
                  System.out.println("error, " + e);
              }
          }
      
      }
      

      ??創建子類:

      public class ChildSalesman extends SuperSalesman {
      
          public static void main(String[] args) {
              ChildSalesman child = new ChildSalesman();
              child.childSaleTickets();
          }
      
          public synchronized void childSaleTickets() {
              while (ticketNum > 0) {
                  ticketNum --;
                  System.out.println("子類售票后,余票為:" + ticketNum
                          + " " + Thread.currentThread().getName());
                  superSaleTickets(); //允許進入,synchronized的可重入性
              }
          }
      
          @Override
          public synchronized void superSaleTickets() {
              System.out.println("I am working");
              super.superSaleTickets();
          }
      }
      

      ??現在運行一下上面的父子類繼承代碼,我們看一下結果:

      子類售票后,余票為:9 main
      I am working
      父類售票后,剩余票數:8 main
      子類售票后,余票為:7 main
      I am working
      父類售票后,剩余票數:6 main
      子類售票后,余票為:5 main
      I am working
      父類售票后,剩余票數:4 main
      子類售票后,余票為:3 main
      I am working
      父類售票后,剩余票數:2 main
      子類售票后,余票為:1 main
      I am working
      父類售票后,剩余票數:0 main
      
      Process finished with exit code 0
      

      ??現在可以驗證出 synchronized 是可重入鎖了吧!因為這些方法輸出了相同的線程名稱,表明即使遞歸調用synchronized修飾的方法,也沒有發生死鎖,證明其是可重入的。

      ??下面是多個方法嵌套調用的例子:

      public class SyncTest {
      
          public static void main(String[] args) {
              LockTest lock = new LockTest();
              lock.method1();
          }
      }
      
      public class LockTest {
          public synchronized void method1() {
              System.out.println("method1");
              method2();
          }
      
          public synchronized void method2() {
              System.out.println("method2");
              method3();
          }
      
          public synchronized void method3() {
              System.out.println("method3");
          }
      }
      

      ??執行main方法,控制臺打印信息如下,說明不會因為之前已經獲取過鎖還沒釋放而發生阻塞。即同一線程可執行多個持有同一把鎖的方法。

      /Library/Java/JavaVirtualMachines/jdk-17.0.2.jdk ...
      method1
      method2
      method3
      

      ??可以看到調用的三個方法均得到了執行。我們知道synchronized修飾普通方法時,使用的是對象鎖,也就是SuperSalesman對象。三個方法的鎖都是SuperSalesman對象。我們在子類中執行childSaleTickets方法時,獲取了SuperSalesman對象鎖,然后在childSomeString時調用了重寫父類的superSaleTickets方法,該方法的鎖也是SuperSalesman對象鎖,然后在其中調用父類的superSaleTickets方法,該方法的鎖也是SuperSalesman對象鎖。一個鎖多次請求,而且都成功了,所以synchronized是可重入鎖。

      ??所以在 java 內部,同一線程在調用自己類中其它 synchronized 方法/塊或調用父類的 synchronized 方法/塊都不會阻礙該線程的執行。就是說同一線程對同一個對象鎖是可重入的,而且同一個線程可以獲取同一把鎖多次,也就是可以多次重入。因為java線程是基于“每個線程(per-thread)”,而不是基于“每次調用(per-invocation)”的(java中線程獲得對象鎖的操作是以線程為粒度的,per-invocation 互斥體獲得對象鎖的操作是以每次調用作為粒度的)。

      可重入鎖的實現原理

      ??看到這里,你終于明白了 synchronized 是一個可重入鎖。但是面試官要再問你,可重入鎖的原理是什么?

      解釋一

      ??可重入鎖實現可重入性原理或機制是:每一把鎖關聯一個線程持有者和計數器,當計數器為 0 時表示該鎖沒有被任何線程持有,那么任何線程都可能獲得該鎖而調用相應的方法;當某一線程請求成功后,JVM會記下鎖的持有線程,并且將計數器置為 1;此時其它線程請求該鎖,則必須等待;而該持有鎖的線程如果再次請求這把鎖,就可以再次拿到這把鎖,同時計數器會遞增;當線程退出同步代碼塊時,計數器會遞減,如果計數器為 0,則釋放該鎖。

      解釋二

      ??通過javap -c SynchronizedLock.class 反編譯,來解析synchronized可重入鎖原理:synchronized通過monitor計數器實現,當執行monitorenter命令時:判斷當前monitor計數器值是否為0,如果為0,則說明當前線程可直接獲取當前鎖對象;否則,判斷當前線程是否和獲取鎖對象線程是同一個線程。若是同一個線程,則monitor計數器累加1,當前線程能再次獲取到鎖;若不是同一個線程,則只能等待其它線程釋放鎖資源。當執行完synchronized鎖對象的代碼后,就會執行monitorexit命令,此時monitor計數器就減1,直至monitor計數器為0時,說明鎖被釋放了。

      結束語

      ??如果您覺得本文對您有幫助,請點一下“推薦”按鈕,您的【推薦】將是我最大的寫作動力!歡迎各位轉載,但是未經作者本人同意,轉載文章之后必須在文章頁面明顯位置給出作者和原文連接;否則,樓蘭胡楊保留追究法律責任的權利。

      Reference

      posted @ 2022-04-03 17:00  樓蘭胡楊  閱讀(2575)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 免费吃奶摸下激烈视频| 亚洲日本高清一区二区三区| 亚洲成色精品一二三区| 国产亚洲综合欧美视频| 四川少妇被弄到高潮| 国产老头多毛Gay老年男| 亚洲精品岛国片在线观看| 丰满无码人妻热妇无码区 | 人人爽人人爽人人片a免费| 天堂mv在线mv免费mv香蕉| 久久国产精品99久久蜜臀| 国产精品乱人伦一区二区| 精品人妻丰满久久久a| 国产精品中文字幕观看| 亚洲国产精品老熟女乱码| 国产一区二区三区色成人| 亚洲成在人线在线播放无码| 亚洲无线码一区在线观看 | 日韩精品av一区二区三区| 欧洲精品码一区二区三区| 久久SE精品一区精品二区| 亚洲成a∨人片在线观看不卡| 亚洲欧美另类激情综合区蜜芽| 亚洲一区二区日韩综合久久| 久久久亚洲欧洲日产国码606| 喀喇沁旗| 国产久免费热视频在线观看 | 久久蜜臀av一区三区| 偷自拍另类亚洲清纯唯美| 伊人精品成人久久综合97| 亚洲日本韩国欧美云霸高清| 亚洲第一二三区日韩国产| 亚洲视频免费一区二区三区| 国产一区二区日韩经典| 免费国产好深啊好涨好硬视频| 免费观看欧美猛交视频黑人 | 亚洲AV无码AV在线影院| 石景山区| 日韩成人午夜精品久久高潮| 亚洲精品无码日韩国产不卡av| 国产自产在线视频一区|