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

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

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

    xylz,imxylz

    關注后端架構、中間件、分布式和并發(fā)編程

       :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      111 隨筆 :: 10 文章 :: 2680 評論 :: 0 Trackbacks

    在這一部分開始討論數(shù)組原子操作和一些其他的原子操作。

    AtomicIntegerArray/AtomicLongArray/AtomicReferenceArray的API類似,選擇有代表性的AtomicIntegerArray來描述這些問題。

    int get(int i)

    獲取位置 i 的當前值。很顯然,由于這個是數(shù)組操作,就有索引越界的問題(IndexOutOfBoundsException異常)。

     

    對于下面的API起始和AtomicInteger是類似的,這種通過方法、參數(shù)的名稱就能夠得到函數(shù)意義的寫法是非常值得稱贊的。在《重構:改善既有代碼的設計》《代碼整潔之道》中都非常推崇這種做法。


    void set(int i, int newValue)
    void lazySet(int i, int newValue)
    int getAndSet(int i, int newValue)
    boolean compareAndSet(int i, int expect, int update)
    boolean weakCompareAndSet(int i, int expect, int update)
    int getAndIncrement(int i)
    int getAndDecrement(int i)
    int getAndAdd(int i, int delta)
    int incrementAndGet(int i)
    int decrementAndGet(int i)
    int addAndGet(int i, int delta)

     

    整體來說,數(shù)組的原子操作在理解上還是相對比較容易的,這些API就是有多使用才能體會到它們的好處,而不僅僅是停留在理論階段。

    現(xiàn)在關注字段的原子更新。

    AtomicIntegerFieldUpdater<T>/AtomicLongFieldUpdater<T>/AtomicReferenceFieldUpdater<T,V>是基于反射的原子更新字段的值。

    相應的API也是非常簡單的,但是也是有一些約束的。

    (1)字段必須是volatile類型的!在后面的章節(jié)中會詳細說明為什么必須是volatile,volatile到底是個什么東西。

    (2)字段的描述類型(修飾符public/protected/default/private)是與調(diào)用者與操作對象字段的關系一致。也就是說調(diào)用者能夠直接操作對象字段,那么就可以反射進行原子操作。但是對于父類的字段,子類是不能直接操作的,盡管子類可以訪問父類的字段。

    (3)只能是實例變量,不能是類變量,也就是說不能加static關鍵字。

    (4)只能是可修改變量,不能使final變量,因為final的語義就是不可修改。實際上final的語義和volatile是有沖突的,這兩個關鍵字不能同時存在。

    (5)對于AtomicIntegerFieldUpdaterAtomicLongFieldUpdater只能修改int/long類型的字段,不能修改其包裝類型(Integer/Long)。如果要修改包裝類型就需要使用AtomicReferenceFieldUpdater。

     

    在下面的例子中描述了操作的方法。

     

    package xylz.study.concurrency.atomic;

    import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

    public class AtomicIntegerFieldUpdaterDemo {

      
    class DemoData{
          
    public volatile int value1 = 1;
          
    volatile int value2 = 2;
          
    protected volatile int value3 = 3;
          
    private volatile int value4 = 4;
       }

        AtomicIntegerFieldUpdater
    <DemoData> getUpdater(String fieldName) {
           
    return AtomicIntegerFieldUpdater.newUpdater(DemoData.class, fieldName);
        }

       
    void doit() {
            DemoData data
    = new DemoData();
            System.out.println(
    "1 ==> "+getUpdater("value1").getAndSet(data, 10));
            System.out.println(
    "3 ==> "+getUpdater("value2").incrementAndGet(data));
            System.out.println(
    "2 ==> "+getUpdater("value3").decrementAndGet(data));
            System.out.println(
    "true ==> "+getUpdater("value4").compareAndSet(data, 4, 5));
        }

       
    public static void main(String[] args) {
            AtomicIntegerFieldUpdaterDemo demo
    = new AtomicIntegerFieldUpdaterDemo();
            demo.doit();
        }

    }
     


    在上面的例子中DemoData的字段value3/value4對于AtomicIntegerFieldUpdaterDemo類是不可見的,因此通過反射是不能直接修改其值的。

     

    AtomicMarkableReference類描述的一個<Object,Boolean>的對,可以原子的修改Object或者Boolean的值,這種數(shù)據(jù)結(jié)構在一些緩存或者狀態(tài)描述中比較有用。這種結(jié)構在單個或者同時修改Object/Boolean的時候能夠有效的提高吞吐量。

     

    AtomicStampedReference類維護帶有整數(shù)“標志”的對象引用,可以用原子方式對其進行更新。對比AtomicMarkableReference類的<Object,Boolean>,AtomicStampedReference維護的是一種類似<Object,int>的數(shù)據(jù)結(jié)構,其實就是對對象(引用)的一個并發(fā)計數(shù)。但是與AtomicInteger不同的是,此數(shù)據(jù)結(jié)構可以攜帶一個對象引用(Object),并且能夠?qū)Υ藢ο蠛陀嫈?shù)同時進行原子操作。

    在后面的章節(jié)中會提到“ABA問題”,而AtomicMarkableReference/AtomicStampedReference在解決“ABA問題”上很有用


    原子操作的使用大概就是這么多,大體來說還算是比較清晰的,在下一個章節(jié)中,將對象原子操作進行總結(jié),重點介紹下原子操作的原理和設計思想。



    ©2009-2014 IMXYLZ |求賢若渴
    posted on 2010-07-02 14:19 imxylz 閱讀(48169) 評論(6)  編輯  收藏 所屬分類: J2EE

    評論

    # re: 深入淺出 Java Concurrency (3): 原子操作 part 2 2010-07-02 21:33 18傲骨中文
    又是高深學堂~~~  回復  更多評論
      

    # re: 深入淺出 Java Concurrency (3): 原子操作 part 2 2010-07-03 10:22 FineReport——報表技術領跑者
    很好很強大,哈哈!頂了~  回復  更多評論
      

    # re: 深入淺出 Java Concurrency (3): 原子操作 part 2[未登錄] 2010-11-23 17:48 Nicholas
    在上面的例子中DemoData的字段value3/value4對于AtomicIntegerFieldUpdaterDemo類是不可見的,因此通過反射是不能直接修改其值的。

    老實說,這句我實在沒有看懂,根據(jù)debug的結(jié)果來看,data中的value3值確實最終變?yōu)榱?.  回復  更多評論
      

    # re: 深入淺出 Java Concurrency (3): 原子操作 part 2 2010-11-23 20:22 xylz
    @Nicholas
    看上面約束2。
    換句話說DemoData的value3/value4字段的修飾符protected/private導致這兩個字段對于類AtomicIntegerFieldUpdaterDemo 來說是不可見的,因此不能夠通過AtomicIntegerFieldUpdater來修改此值。因此運行時下面兩句會得到一個非法訪問的異常。
    System.out.println("2 ==> "+getUpdater("value3").decrementAndGet(data));
    System.out.println("true ==> "+getUpdater("value4").compareAndSet(data, 4, 5));  回復  更多評論
      

    # re: 深入淺出 Java Concurrency (3): 原子操作 part 2 2013-06-13 11:38 海藍
    應該是可見的吧@xylz
      回復  更多評論
      

    # re: 深入淺出 Java Concurrency (3): 原子操作 part 2 2016-03-10 16:30 問問問問
    @Nicholas
    @海藍
    對啊,默認的可以訪問到,protected怎么可能訪問不到  回復  更多評論
      


    ©2009-2014 IMXYLZ
    主站蜘蛛池模板: 国产午夜鲁丝片AV无码免费| 久久久久久久国产免费看| 一区二区在线免费观看| 在线A亚洲老鸭窝天堂| 精品免费AV一区二区三区| 日本大片在线看黄a∨免费| 亚洲AV成人一区二区三区在线看| 一个人看的www免费视频在线观看 一个人免费视频观看在线www | 亚洲第一成人在线| 91精品国产免费久久久久久青草 | 成人免费淫片在线费观看| 亚洲人成7777| 日韩成人免费在线| 美女黄频免费网站| 日韩精品亚洲aⅴ在线影院| a色毛片免费视频| 亚洲色图视频在线观看| 国产桃色在线成免费视频| 亚洲欧美日韩综合久久久久 | 亚洲?v无码国产在丝袜线观看| 羞羞网站免费观看| 亚洲精品夜夜夜妓女网| 日韩插啊免费视频在线观看| 亚洲六月丁香六月婷婷蜜芽| 日本不卡免费新一二三区| 一区二区3区免费视频| 亚洲国产精品久久久天堂| 最近中文字幕电影大全免费版| 亚洲综合色7777情网站777| 免费乱理伦在线播放| 中国毛片免费观看| 亚洲三级中文字幕| 亚洲精品国产精品国自产观看| 国产免费AV片在线观看| 国产午夜亚洲精品| 精品国产亚洲一区二区在线观看| 四虎影视在线影院在线观看免费视频 | 久久国内免费视频| 手机永久免费的AV在线电影网| 午夜亚洲国产理论秋霞| 在线免费观看视频你懂的|