悲觀的併發策略——synchronized互斥鎖

互斥鎖是最多見的同步手段,在併發過程當中,當多條線程對同一個共享數據競爭時,它保證共享數據同一時刻只能被一條線程使用,其餘線程只有等到鎖釋放後才能從新進行競爭。bash

對於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,提供了方便的同時也體現出了本身的侷限性。this

-------------推薦閱讀------------spa

個人2017文章彙總——機器學習篇

個人2017文章彙總——Java及中間件

個人2017文章彙總——深度學習篇

個人2017文章彙總——JDK源碼篇

個人2017文章彙總——天然語言處理篇

個人2017文章彙總——Java併發篇

------------------廣告時間----------------

跟我交流,向我提問:

這裏寫圖片描述

公衆號的菜單已分爲「分佈式」、「機器學習」、「深度學習」、「NLP」、「Java深度」、「Java併發核心」、「JDK源碼」、「Tomcat內核」等,可能有一款適合你的胃口。

爲何寫《Tomcat內核設計剖析》

歡迎關注:

這裏寫圖片描述
相關文章
相關標籤/搜索