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

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

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

    posts - 12, comments - 8, trackbacks - 0, articles - 5
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    [轉]CAS原理

    Posted on 2010-11-18 15:16 楊羅羅 閱讀(3128) 評論(1)  編輯  收藏 所屬分類: java.thread

    在JDK 5之前Java語言是靠synchronized關鍵字保證同步的,這會導致有鎖(后面的章節還會談到鎖)。

    鎖機制存在以下問題:

    (1)在多線程競爭下,加鎖、釋放鎖會導致比較多的上下文切換和調度延時,引起性能問題。

    (2)一個線程持有鎖會導致其它所有需要此鎖的線程掛起。

    (3)如果一個優先級高的線程等待一個優先級低的線程釋放鎖會導致優先級倒置,引起性能風險。

    volatile是不錯的機制,但是volatile不能保證原子性。因此對于同步最終還是要回到鎖機制上來。

    獨占鎖是一種悲觀鎖,synchronized就是一種獨占鎖,會導致其它所有需要鎖的線程掛起,等待持有鎖的線程釋放鎖。而另一個更加有效的鎖就是樂觀鎖。所謂觀鎖就是,每次不加鎖而是假設沒有沖突而去完成某項操作,如果因為沖突失敗就重試,直到成功為止。

    CAS 操作

    上面的樂觀鎖用到的機制就是CAS,Compare and Swap。

    CAS有3個操作數,內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改為B,否則什么都不做。

    非阻塞算法 (nonblocking algorithms)

    一個線程的失敗或者掛起不應該影響其他線程的失敗或掛起的算法。

    現代的CPU提供了特殊的指令,可以自動更新共享數據,而且能夠檢測到其他線程的干擾,而 compareAndSet() 就用這些代替了鎖定。

    拿出AtomicInteger來研究在沒有鎖的情況下是如何做到數據正確性的。

    private volatile int value;

    首先毫無以為,在沒有鎖的機制下可能需要借助volatile原語,保證線程間的數據是可見的(共享的)。這樣才獲取變量的值的時候才能直接讀取。

    public final int get() {
            return value;
        }

    然后來看看++i是怎么做到的。

    public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }

    在這里采用了CAS操作,每次從內存中讀取數據然后將此數據和+1后的結果進行CAS操作,如果成功就返回結果,否則重試直到成功為止。

    而compareAndSet利用JNI來完成CPU指令的操作。

    public final boolean compareAndSet(int expect, int update) {   
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
        }

    整體的過程就是這樣子的,利用CPU的CAS指令,同時借助JNI來完成Java的非阻塞算法。其它原子操作都是利用類似的特性完成的。

    而整個J.U.C都是建立在CAS之上的,因此對于synchronized阻塞算法,J.U.C在性能上有了很大的提升。

    CAS看起來很爽,但是會導致“ABA問題”。

    CAS算法實現一個重要前提需要取出內存中某時刻的數據,而在下時刻比較并替換,那么在這個時間差類會導致數據的變化

    比如說一個線程one從內存位置V中取出A,這時候另一個線程two也從內存中取出A,并且two進行了一些操作變成了B,然后two又將V位置的數據變成A,這時候線程one進行CAS操作發現內存中仍然是A,然后one操作成功。盡管線程one的CAS操作成功,但是不代表這個過程就是沒有問題的。如果鏈表的頭在變化了兩次后恢復了原值,但是不代表鏈表就沒有變化。因此前面提到的原子操作AtomicStampedReference/AtomicMarkableReference就很有用了。這允許一對變化的元素進行原子操作。


    評論

    # re: [轉]CAS原理  回復  更多評論   

    2012-10-16 17:24 by 超凡
    好東西!
    主站蜘蛛池模板: 岛国精品一区免费视频在线观看 | 亚洲国产精品国产自在在线| 免费一级毛片在线播放放视频| 亚洲美女高清一区二区三区| 久久久久久国产精品免费免费男同 | 日韩激情淫片免费看| 四虎国产精品成人免费久久| 亚洲an天堂an在线观看| 嫩草影院免费观看| 182tv免费视频在线观看| 亚洲国产视频久久| 国产亚洲精品一品区99热| 毛片免费vip会员在线看| 精品无码国产污污污免费网站国产 | 久久综合九色综合97免费下载| 亚洲精品天堂在线观看| 伊人久久大香线蕉亚洲五月天 | 亚洲精品自产拍在线观看动漫| 午夜高清免费在线观看| 毛片在线全部免费观看| 国产成人综合亚洲绿色| 老色鬼久久亚洲AV综合| 亚洲精品国产自在久久| 一二三四在线播放免费观看中文版视频| 一区在线免费观看| 亚洲色最新高清av网站| 亚洲国产国产综合一区首页| 国产亚洲精品免费| 免费精品人在线二线三线区别| a级毛片免费在线观看| 婷婷亚洲综合五月天小说在线| 97亚洲熟妇自偷自拍另类图片| 亚洲国产午夜福利在线播放| 毛片免费观看网站| 日韩精品无码一区二区三区免费| jzzijzzij在线观看亚洲熟妇| 亚洲精品网站在线观看你懂的| 亚洲精品乱码久久久久久| 又大又硬又爽免费视频| 免费高清在线影片一区| 99在线精品免费视频九九视|