<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    java技術研究

    統計

    留言簿(3)

    閱讀排行榜

    評論排行榜

    Lock和synchronized (轉)

        JDK1.5以后,在鎖機制方面引入了新的鎖-Lock,在網上的說法都比較籠統,結合網上的信息和我的理解這里做個總結。 

        java現有的鎖機制有兩種實現方式,J.DK1.4前是通過synchronized實現,JDK1.5后加入java.util.concurrent.locks包下的各種lock(以下簡稱Lock) 

        先說說代碼層的區別。 
        synchronized:在代碼里,synchronized類似“面向對象”,修飾類、方法、對象。 
        Lock:不作為修飾,類似“面向過程”,在方法中需要鎖的時候lock,在結束的時候unlock(一般都在finally塊里)。 
    例如代碼: 

    Java代碼  收藏代碼
    1. public void method1() {  
    2.     synchronized(this){//舊鎖,無需人工釋放  
    3.         System.out.println(1);  
    4.     }  
    5. }  
    6.       
    7. public void method2() {  
    8.     Lock lock = new ReentrantLock();  
    9.     lock.lock();//上鎖  
    10.     try{  
    11.         System.out.println(2);  
    12.     }finally{  
    13.         lock.unlock();//解鎖  
    14.     }  
    15. }  

        其次說說性能。 
        相關的性能測試網上已經有很多,這里也直接拿來主義,給出結論: 
        在并發高是,luck性能優勢很明顯,在低并發時,synchronized也能取得優勢。具體的臨界范圍比較難定論,下面會討論。 

        現在來分析它們具體的區別。 
        鎖都是 原子性 的,也可以理解為鎖是否在使用的標記,并且比較和設置這個標記的操作是原子性的,不同硬件平臺上的jdk實現鎖的相關方法都是native的(比如park/unpark),所以不同平臺上鎖的精確度的等級由這些native的方法決定。所以網上經常可以看見的結論是“Lock比synchronized有更精確的原子操作”說的也是native方法(不得不感慨C才是硬件王道)。 


    下面繼續討論怎么由代碼層到native的過程。 
    1、所有對象都自動含有單一的鎖,JVM負責跟蹤對象被加鎖的次數。如果一個對象被解鎖,其計數變為0。在任務(線程)第一次給對象加鎖的時候,計數變為1。每當這個相同的任務(線程)在此對象上獲得鎖時,計數會遞增。 只有首先獲得鎖的任務(線程)才能繼續獲取該對象上的多個鎖。每當任務離開時,計數遞減,當計數為0的時候,鎖被完全釋放。synchronized就是基于這個原理,同時synchronized靠某個對象的單一鎖技術的次數來判斷是否被鎖,所以無需(也不能)人工干預鎖的獲取和釋放。如果結合方法調用時的棧和框架(如果對方法的調用過程不熟悉建議看看http://wupuyuan.iteye.com/blog/1157548),不難推測出synchronized原理是基于棧中的某對象來控制一個框架,所以對于synchronized有常用的優化是鎖對象不鎖方法。實際上synchronized作用于方法時,鎖住的是“this”,作用于靜態方法/屬性時,鎖住的是存在于永久帶的CLASS,相當于這個CLASS的全局鎖,鎖作用于一般對象時,鎖住的是對應代碼塊。在HotSpot中JVM實現中,鎖有個專門的名字:對象監視器。 


    當多個線程同時請求某個對象監視器時,對象監視器會設置幾種狀態用來區分請求的線程 
    Contention List:所有請求鎖的線程將被首先放置到該競爭隊列,是個虛擬隊列,不是實際的Queue的數據結構。
    Entry List:EntryList與ContentionList邏輯上同屬等待隊列,ContentionList會被線程并發訪問,為了降低對ContentionList隊尾的爭用,而建立EntryList。,Contention List中那些有資格成為候選人的線程被移到Entry List 
    Wait Set:那些調用wait方法被阻塞的線程被放置到Wait Set 
    OnDeck:任何時刻最多只能有一個線程正在競爭鎖,該線程稱為OnDeck 
    Owner:獲得鎖的線程稱為Owner 
    !Owner:釋放鎖的線程 

    2、Lock不同于synchronized面向對象,它基于棧中的框架而不是某個具體對象,所以Lock只需要在棧里設置鎖的開始和結束(lock和unlock)的地方就行了(人工必須標明),不用關心框架大小對象的變化等等。這么做的好處是Lock能提供無條件的、可輪詢的、定時的、可中斷的鎖獲取操作,相對于synchronized來說,synchronized的鎖的獲取是釋放必須在一個模塊里,獲取和釋放的順序必須相反,而Lock則可以在不同范圍內獲取釋放,并且順序無關。java.util.concurrent.locks下的鎖類很類似,依賴于java.util.concurrent.AbstractQueuedSynchronizer,它們把所有的Lock接口操作都轉嫁到Sync類上,這個類繼承了AbstractQueuedSynchronizer,它同時還包含子2個類:NonfairSync 和FairSync 從名字上可以看的出是為了實現公平和非公平性。AbstractQueuedSynchronizer中把所有的的請求線程構成一個隊列(一樣也是虛擬的),具體的實現可以參考http://blog.csdn.net/chen77716/article/details/6641477#,這里我就不復制了。 

    3、從jdk的源代碼來看,Lock和synchronized的源碼基本相同,區別主要在維護的同步隊列上。再往下深究就到了native方法了。 

    4、還有個改進我也想說下,其實很重要的。線程分阻塞(wait)和非阻塞狀態,阻塞狀態由操作系統(linux、windows等)完成,當前一個被“鎖”的線程執行完畢后,有可能在后續的線程隊列里還沒分配出一個獲取鎖而被“喚醒”的非阻塞線程,即所有線程還都是阻塞狀態時,就被系統調度(進入內核的線程是阻塞的),這樣會導致內核在用戶態和內核態之間來回接換,嚴重影響鎖的性能。在jdk1.6以前主要靠自旋鎖來解決,原理是在前一個線程結束后,爭用線程可以做一個空循環,繼續占有CPU,等待取鎖的機會。當然這樣做顯然也是浪費時間,只是在兩種浪費中選取浪費少的……  jdk1.6后引入了偏向鎖,當線程第一次獲得了監視對象,之后讓監視對象“偏向”這個線程,之后的多次調用則可以避免CAS操作,等于是置了一臨時變量來記錄位置(類似索引比較)。詳細的就涉及到匯編指令了,我也就沒太深究,偏向鎖性能優于自旋鎖,但是還是沒有達到HotSpot認為的最佳時間(一個線程上下文切換的時間)。 

        綜合來看對于所有的高并發情況,采用Lock加鎖是最優選擇,但是由于歷史遺留等問題,synchronized也還是不能完全被淘汰,同時,在低并發情況下,synchronized的性能還是比Lock好的。 

    原帖地址:http://wupuyuan.iteye.com/blog/1158655

    posted on 2015-10-27 19:08 小秦 閱讀(303) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 一本色道久久88亚洲综合 | 国产成人1024精品免费| 国内免费高清在线观看| 亚洲精品视频在线观看免费| 久久99精品免费视频| 亚洲AV乱码一区二区三区林ゆな| 国产成人无码区免费内射一片色欲 | 亚洲AV无码乱码在线观看性色扶 | 四虎免费影院ww4164h| 亚洲自偷自拍另类图片二区| 在线免费观看亚洲| 无码欧精品亚洲日韩一区| 免费无码又爽又刺激一高潮| 久久久久久a亚洲欧洲AV| 99精品热线在线观看免费视频| 亚洲精品视频免费在线观看| 国产一卡二卡3卡四卡免费 | a一级毛片免费高清在线| 亚洲国产精品无码AAA片| 巨波霸乳在线永久免费视频 | 男女超爽视频免费播放| 国产综合精品久久亚洲| 色欲A∨无码蜜臀AV免费播| 亚洲成人黄色在线| 麻豆成人精品国产免费| 一级毛片免费不卡直观看| 亚洲av激情无码专区在线播放 | 精品国产福利尤物免费| 久久精品国产亚洲AV麻豆网站| AV片在线观看免费| 九九九精品视频免费| 亚洲无线电影官网| 国产成人无码a区在线观看视频免费 | 亚洲熟妇AV一区二区三区浪潮| 亚洲精品第一国产综合境外资源| 国产成人精品无码免费看| 亚洲精品无码av片| 久久99国产亚洲高清观看首页 | 成人黄18免费视频| 久青草视频在线观看免费| 亚洲人成日本在线观看|