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

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

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

    卓凡

     

    (轉)volatile原理與技巧

    volatile, 用更低的代價替代同步

    為什么 使用volatile比同步代價更低?
    同步的代價, 主要由其覆蓋范圍決定, 如果可以降低同步的覆蓋范圍, 則可以大幅提升程序性能.

    而volatile的覆蓋范圍僅僅變量級別的. 因此它的同步代價很低.

    volatile原理是什么?
    volatile的語義, 其實是告訴處理器, 不要將我放入工作內存, 請直接在主存操作我.(工作內存詳見java內存模型)

    因此, 當多核或多線程在訪問該變量時, 都將直接 操作 主存, 這從本質上, 做到了變量共享.

    volatile的有什么優勢?
    1, 更大的程序吞吐量
    2, 更少的代碼實現多線程
    3, 程序的伸縮性較好
    4, 比較好理解, 無需太高的學習成本

    volatile有什么劣勢?
    1, 容易出問題
    2, 比較難設計

    volatile運算存在臟數據問題

    volatile僅僅能保證變量可見性, 無法保證原子性.

    volatile的race condition示例:

    public class TestRaceCondition {

    private volatile int i = 0;

     

    public void increase() {

    i++;

    }

     

    public int getValue() {

    return i;

    }

    }

    當多線程執行increase方法時, 是否能保證它的值會是線性遞增的呢?
    答案是否定的.

    原因:
    這里的increase方法, 執行的操作是i++, 即 i = i + 1;
    針對i = i + 1, 在多線程中的運算, 本身需要改變i的值.
    如果, 在i已從內存中取到最新值, 但未與1進行運算, 此時其他線程已數次將運算結果賦值給i.
    則當前線程結束時, 之前的數次運算結果都將被覆蓋.

    即, 執行100次increase, 可能結果是 < 100.
    一般來說, 這種情況需要較高的壓力與并發情況下, 才會出現.

    如何避免這種情況?
    解決以上問題的方法:
    一種是 操作時, 加上同步.
    這種方法, 無疑將大大降低程序性能, 且違背了volatile的初衷.

    第二種方式是, 使用硬件原語(CAS), 實現非阻塞算法
    從CPU原語上, 支持變量級別的低開銷同步.

    CPU原語-比較并交換(CompareAndSet),實現非阻塞算法

    什么是CAS?
    cas是現代CPU提供給并發程序使用的原語操作. 不同的CPU有不同的使用規范.

    在 Intel 處理器中,比較并交換通過指令的 cmpxchg 系列實現。
    PowerPC 處理器有一對名為“加載并保留”和“條件存儲”的指令,它們實現相同的目地;
    MIPS 與 PowerPC 處理器相似,除了第一個指令稱為“加載鏈接”。

    CAS 操作包含三個操作數 —— 內存位置(V)、預期原值(A)和新值(B)

    什么是非阻塞算法?
    一個線程的失敗或掛起不應該影響其他線程的失敗或掛起.這類算法稱之為非阻塞(nonblocking)算法

    對比阻塞算法:
    如果有一類并發操作, 其中一個線程優先得到對象監視器的鎖, 當其他線程到達同步邊界時, 就會被阻塞.
    直到前一個線程釋放掉鎖后, 才可以繼續競爭對象鎖.(當然,這里的競爭也可是公平的, 按先來后到的次序)

    CAS 原理:

    我認為位置 V 應該包含值 A;如果包含該值,則將 B 放到這個位置;否則,不要更改該位置,只告訴我這個位置現在的值即可。

    CAS使用示例(jdk 1.5 并發包 AtomicInteger類分析:)

    /**

    * Atomically sets to the given value and returns the old value.

    *

    * @param newValue the new value

    * @return the previous value

    */


    public final int getAndSet(int newValue) {

    for (;;) {

    int current = get();

    if (compareAndSet(current, newValue))

    return current;

    }

    }

     

    public final boolean compareAndSet(int expect, int update) {

    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);

    }

    這個方法是, AtomicInteger類的常用方法, 作用是, 將變量設置為指定值, 并返回設置前的值.
    它利用了cpu原語compareAndSet來保障值的唯一性.

    另, AtomicInteger類中, 其他的實用方法, 也是基于同樣的實現方式.
    比如 getAndIncrement, getAndDecrement, getAndAdd等等.

    CAS語義上存在的 ” ABA 問題”

    什么是ABA問題?
    假設, 第一次讀取V地址的A值, 然后通過CAS來判斷V地址的值是否仍舊為A, 如果是, 就將B的值寫入V地址,覆蓋A值.

    但是, 語義上, 有一個漏洞, 當第一次讀取V的A值, 此時, 內存V的值變為B值, 然后在未執行CAS前, 又變回了A值.
    此時, CAS再執行時, 會判斷其正確的, 并進行賦值.

    這種判斷值的方式來斷定內存是否被修改過, 針對某些問題, 是不適用的.

    為了解決這種問題, jdk 1.5并發包提供了AtomicStampedReference(有標記的原子引用)類, 通過控制變量值的版本來保證CAS正確性.

    其實, 大部分通過值的變化來CAS, 已經夠用了.

    jdk1.5原子包介紹(基于volatile)

    包的特色:
    1, 普通原子數值類型AtomicInteger, AtomicLong提供一些原子操作的加減運算.

    2, 使用了解決臟數據問題的經典模式-”比對后設定”, 即 查看主存中數據是否與預期提供的值一致,如果一致,才更新.

    3, 使用AtomicReference可以實現對所有對象的原子引用及賦值.包括Double與Float,
    但不包括對其的計算.浮點的計算,只能依靠同步關鍵字或Lock接口來實現了.

    4, 對數組元素里的對象,符合以上特點的, 也可采用原子操作.包里提供了一些數組原子操作類
    AtomicIntegerArray, AtomicLongArray等等.

    5, 大幅度提升系統吞吐量及性能.

    具體使用, 詳解java doc.

    原文鏈接:http://kenwublog.com/the-theory-of-volatile

    posted on 2010-01-08 17:57 卓凡 閱讀(173) 評論(0)  編輯  收藏 所屬分類: core java

    導航

    統計

    常用鏈接

    留言簿

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲国产成人片在线观看| 亚洲精品国产日韩无码AV永久免费网| 亚洲AV无码久久精品狠狠爱浪潮| 九九久久国产精品免费热6| 在线观看亚洲免费| 久久亚洲精品成人无码| 精品免费国产一区二区| 亚洲.国产.欧美一区二区三区| 午夜dj免费在线观看| MM1313亚洲国产精品| 亚洲精品乱码久久久久久不卡| 国产一区二区三区亚洲综合| | 久久久久久精品成人免费图片| 噜噜噜亚洲色成人网站∨| 一级毛片**不卡免费播| 亚洲日本视频在线观看| 永久免费无码网站在线观看| 人人爽人人爽人人片A免费| 亚洲综合伊人久久大杳蕉| 国产精品免费高清在线观看| 亚洲国产成人精品无码一区二区| 成年人视频在线观看免费| 成人久久久观看免费毛片| 亚洲日韩精品射精日 | 国产成年无码久久久免费| 自怕偷自怕亚洲精品| 成人免费网站在线观看| 思思久久99热免费精品6| 久久久久亚洲av无码尤物| 毛片a级毛片免费观看免下载| 美女黄频a美女大全免费皮| 国产成A人亚洲精V品无码性色| 在免费jizzjizz在线播| 亚洲av无码日韩av无码网站冲| 久久亚洲国产成人精品无码区| 亚洲成人免费网址| 高潮毛片无遮挡高清免费| 久久精品国产亚洲AV果冻传媒| 成人黄动漫画免费网站视频 | 国产91久久久久久久免费|