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

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

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

    jinfeng_wang

    G-G-S,D-D-U!

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
    http://www.mamicode.com/info-detail-334916.html

    一、自旋鎖提出的背景

          由于在多處理器系統環境中有些資源因為其有限性,有時需要互斥訪問(mutual exclusion),這時會引入鎖的機制,只有獲取了鎖的進程才能獲取資源訪問。即是每次只能有且只有一個進程能獲取鎖,才能進入自己的臨界區,同一時間不能兩個或兩個以上進程進入臨界區,當退出臨界區時釋放鎖。設計互斥算法時總是會面臨一種情況,即沒有獲得鎖的進程怎么辦?通常有2種處理方式。一種是沒有獲得鎖的調用者就一直循環在那里看是否該自旋鎖的保持者已經釋放了鎖,這就是自旋鎖,他不用將縣城阻塞起來(NON-BLOCKING);另一種是沒有獲得鎖的進程就阻塞(BLOCKING)自己,請求OS調度另一個線程上處理器,這就是互斥鎖。

     

    二、自旋鎖原理

          跟互斥鎖一樣,一個執行單元要想訪問被自旋鎖保護的共享資源,必須先得到鎖,在訪問完共享資源后,必須釋放鎖。如果在獲取自旋鎖時,沒有任何執行單元保持該鎖,那么將立即得到鎖;如果在獲取自旋鎖時鎖已經有保持者,那么獲取鎖操作將自旋在那里,直到該自旋鎖的保持者釋放了鎖。由此我們可以看出,自旋鎖是一種比較低級的保護數據結構或代碼片段的原始方式,這種鎖可能存在兩個問題:

    • 遞歸死鎖:試圖遞歸地獲得自旋鎖必然會引起死鎖:遞歸程序的持有實例在第二個實例循環,以試圖獲得相同自旋鎖時,不會釋放此自旋鎖。在遞歸程序中使用自旋鎖應遵守下列策略:遞歸程序決不能在持有自旋鎖時調用它自己,也決不能在遞歸調用時試圖獲得相同的自旋鎖。此外如果一個進程已經將資源鎖定,那么,即使其它申請這個資源的進程不停地瘋狂“自旋”,也無法獲得資源,從而進入死循環。
    • 過多占用cpu資源。如果不加限制,由于申請者一直在循環等待,因此自旋鎖在鎖定的時候,如果不成功,不會睡眠,會持續的嘗試,單cpu的時候自旋鎖會讓其它process動不了. 因此,一般自旋鎖實現會有一個參數限定最多持續嘗試次數. 超出后, 自旋鎖放棄當前time slice. 等下一次機會

    由此可見,自旋鎖比較適用于鎖使用者保持鎖時間比較短的情況。正是由于自旋鎖使用者一般保持鎖時間非常短,因此選擇自旋而不是睡眠是非常必要的,自旋鎖的效率遠高于互斥鎖。

     

    三、Java CAS

          CAS是一種系統原語(所謂原語屬于操作系統用語范疇。原語由若干條指令組成的,用于完成一定功能的一個過程。primitive or atomic action 是由若干個機器指令構成的完成某種特定功能的一段程序,具有不可分割性·即原語的執行必須是連續的,在執行過程中不允許被中斷)。CAS是Compare And Set的縮寫。CAS有3個操作數,內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改為B,否則什么都不做。

         在x86 平臺上,CPU提供了在指令執行期間對總線加鎖的手段。CPU芯片上有一條引線#HLOCK pin,如果匯編語言的程序中在一條指令前面加上前綴"LOCK",經過匯編以后的機器代碼就使CPU在執行這條指令的時候把#HLOCK pin的電位拉低,持續到這條指令結束時放開,從而把總線鎖住,這樣同一總線上別的CPU就暫時不能通過總線訪問內存了,保證了這條指令在多處理器環境中的原子性

          sun.misc.Unsafe是JDK里面的一個內部類,這個類為JDK嚴格保護,因為他提供了大量的低級的內存操作和系統功能。如果因為錯誤的使用了這個類,不會有“異常”被扔出,甚至會造成JVM宕機。這也是為什么這個類的名字是Unsafe的原因。因此當使用這個類的時候,你一定要明白你在干什么。這個類中提供了3個CAS的操作

    方法名解釋
    compareAndSwapInt(Object object, long address, int expected, int newValue) 比較對象object的某個int型的屬性(以地址的方式訪問),如果他的數據值是expected,則設定為newValue,返回true;否則返回false
    compareAndSwapLong(Object object, long address, long expected, long newValue) 比較對象object的某個long型的屬性(以地址的方式訪問),如果他的數據值是expected,則設定為newValue,返回true;否則返回false
    compareAndSwapLong(Object object, long address, Object expected, Object newValue) 比較對象object的某個Object型的屬性(以地址的方式訪問),如果他的數據值是expected,則設定為newValue,返回true;否則返回false

     

    四、Java自旋鎖應用-原子包

    Jdk1.5以后,提供了java.util.concurrent.atomic包,這個包里面提供了一組原子類。其基本的特性就是在多線程環境下,當有多個線程同時執行這些類的實例包含的方法時,具有排他性,即當某個線程進入方法,執行其中的指令時,不會被其他線程打斷,而別的線程就像自旋鎖一樣,一直等到該方法執行完成,才由JVM從等待隊列中選擇一個另一個線程進入,這只是一種邏輯上的理解。實際上是借助硬件的相關指令來實現的,不會阻塞線程(或者說只是在硬件級別上阻塞了)。其中的類可以分成4組

    • AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
    • AtomicIntegerArray,AtomicLongArray
    • AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater
    • AtomicMarkableReference,AtomicStampedReference,AtomicReferenceArray

     

    我們來看一段AtomicBoolean中的自旋鎖的代碼

    public final boolean getAndSet(boolean newValue) {    for (;;) {        boolean current = get();        if (compareAndSet(current, newValue))            return current;    } }

     

     

    參考

    http://baike.baidu.com/view/1250961.htm?fr=aladdin

    posted on 2016-12-14 13:56 jinfeng_wang 閱讀(599) 評論(0)  編輯  收藏

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


    網站導航:
     
    主站蜘蛛池模板: 在线精品亚洲一区二区三区| 四虎影在线永久免费观看| 亚洲AV无码乱码在线观看裸奔| 国产成人亚洲精品91专区高清| 日本一道高清不卡免费| 亚洲色欲色欱wwW在线| 亚洲人成影院在线观看| 亚洲va在线va天堂va888www| 99精品视频在线观看免费| 亚洲精品无码久久久久去q| 今天免费中文字幕视频| 伊人久久综在合线亚洲2019| 国产尤物在线视精品在亚洲| 国产性生交xxxxx免费| 亚洲神级电影国语版| 岛国精品一区免费视频在线观看| 亚洲片国产一区一级在线观看| 福利免费在线观看| 亚洲一区精品中文字幕| 日韩av无码成人无码免费| 亚洲视频在线观看免费| 一级一级一级毛片免费毛片| 2048亚洲精品国产| 98精品全国免费观看视频| 最新亚洲春色Av无码专区| 国产精品久久免费视频| 久久国产福利免费| 亚洲国产成人va在线观看网址| 日韩精品免费一区二区三区| j8又粗又长又硬又爽免费视频| 亚洲国产人成在线观看69网站| 黄页网站免费观看| 一级毛片大全免费播放下载| 亚洲另类激情综合偷自拍| 热久久精品免费视频| 亚洲精品国产首次亮相| 久久精品国产亚洲7777| 久香草视频在线观看免费| 亚洲综合成人网在线观看| 国产精品99久久免费| 久久精品私人影院免费看|