<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>

                volatile既然不足以保證數據同步,那么就必須要引入鎖來確保。互斥鎖是最常見的同步手段,在并發過程中,當多條線程對同一個共享數據競爭時,它保證共享數據同一時刻只能被一條線程使用,其他線程只有等到鎖釋放后才能重新進行競爭。對于java開發人員,我們最熟悉的肯定就是用synchronized關鍵詞完成鎖功能,在涉及到多線程并發時,對于一些變量,你應該會毫不猶豫地加上synchronized去保證變量的同步性。 在C/C++可直接使用操作系統提供的互斥鎖實現同步和線程的阻塞和喚起,與之不同的是,java要把這些底層封裝,而synchronized就是一個典型的互斥鎖,同時它也是一個JVM級別的鎖,它的實現細節全部封裝在JVM中實現,對開發人員只提供了synchronized關鍵詞。根據鎖的顆粒度,可以用synchronized對一個變量、一個方法、一個對象和一個類等加鎖。被synchronized修飾的程序塊經過編譯后,會在前后生成monitorenter和monitorexit兩個字節碼指令,其中涉及到鎖定和解鎖對象的確定,這就要根據synchronized來確定了,假如明確指定了所對象,例如synchronized(變量)、synchronized(this)等,說明加解鎖對象為變量或運行時對象。假如沒有明確指定對象,則根據synchronized修飾的方法去找對應的鎖對象,如修飾一個非靜態方法表示此方法對應的對象為鎖對象,如修飾一個靜態方法則表示此方法對應的類對象為鎖對象。當一個對象被鎖住時,對象里面所有用synchronized修飾的方法都將產生堵塞,而對象里非synchronized修飾的方法可正常被調用,不收鎖影響。 為了實現互斥鎖,JVM的monitorenter和monitorexit字節碼依賴底層操作系統的互斥鎖來實現,java層面的線程與操作系統的原生線程有映射關系,這時如果要將一個線程進行阻塞或喚起都需要操作系統的協助,這就需要從用戶態切換到內核態來執行,這種切換代價十分昂貴,需要消耗很多處理器時間。如果可能,應該減少這樣的切換,jvm一般會采取一些措施進行優化,例如在把線程進行阻塞操作之前先讓線程自旋等待一段時間,可能在等待期間其他線程已經解鎖,這時就無需再讓線程執行阻塞操作,避免了用戶態到內核態的切換。 Synchronized還有另外一個重要的特性——可重入性。這個特性主要是針對當前線程而言的,可重入即是自己可以再次獲得自己的內部鎖,在嘗試獲取對象鎖時,如果當前線程已經擁有了此對象的鎖,則把鎖的計數器加一,在釋放鎖時則對應地減一,當鎖計數器為0時表示鎖完全被釋放,此時其他線程可對其加鎖。可重入特性是為了解決自己鎖死自己的情況,如下面偽代碼: public class DeadLock{ public synchronized void method1(){} public synchronized void method2(){ this.method1(); } public static void main(String[] args){ ??DeadLock deadLock=new DeadLock(); ?? deadLock.method2(); } } 這種情況其實也并非不常見,一個類中的同步方法調用另一個同步方法,假如synchronized不支持重入,進入method2方法時當前線程將嘗試獲取deadLock對象的鎖,而method2方法里面執行method1方法時,當前線程又要去嘗試獲取deadLock對象的鎖,這時由于不支持重入,它要去等deadLock對象的鎖釋放,把自己阻塞了,這就是自己鎖死自己的現象。所以重入機制的引入,杜絕了這種情況的發生。 synchronized實現的是一個非公平鎖,非公平主要表現在獲取鎖的行為上,并非是按照申請鎖的時間前后給等待線程分配鎖的,每當鎖被釋放后,任何一個線程都有機會競爭到鎖,這樣做的目的是為了提高執行性能,當然也會產生線程饑餓現象。 synchronized最后一個特性(缺點)就是不可中斷性,在所有等待的線程中,你們唯一能做的就是等,而實際情況可能是有些任務等了足夠久了,我要取消此任務去干別的事情,此時synchronized是無法幫你實現的,它把所有實現機制都交給了JVM,提供了方便的同時也體現出了自己的局限性。 這節主要介紹java的synchronized關鍵詞,包括它的作用及JVM及操作系統的底層實現,它的可重入性和不可中斷性,它實現的是一個非公平的互斥鎖,同時它也是一個悲觀的并發策略,不管是否會產生競爭,任何的數據操作都必須要加鎖。對synchronized深入全面的理解對理解tomcat中跟多線程并發相關的模塊是很有幫助的。 喜歡研究java的同學可以交個朋友,下面是本人的微信號: ![](https://box.kancloud.cn/2016-01-15_5698bd8d22882.jpg)
                  <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>

                              哎呀哎呀视频在线观看