zoukankan      html  css  js  c++  java
  • 无锁工具类:原子类

    累加器例子:add10K() 这个方法不是线程安全的,问题就出在变量 count 的可见性和 count+=1 的原子性上

    1.可见性问题可以用 volatile 来解决,
    
    2.原子性问题我一直都是采用的互斥锁。
    public class Test {
      long count = 0;
      void add10K() {
        int idx = 0;
        while(idx++ < 10000) {
          count += 1;
        }
      }
    }

    对于简单的原子性问题,还有一种无锁方案:

    1.将原来的 long 型变量 count 替换为了原子类 AtomicLong,
    
    2.原来的 count +=1 替换成了 count.getAndIncrement(),
    
    3.仅需要这两处简单的改动就能使 add10K() 方法变成线程安全的
    public class Test {
      AtomicLong count = 
        new AtomicLong(0);
      void add10K() {
        int idx = 0;
        while(idx++ < 10000) {
          count.getAndIncrement();
        }
      }
    }

    无锁方案优势:性能

    1.互斥锁方案为了保证互斥性,
        1) 需要执行加锁、解锁操作,而加锁、解锁操作本身就消耗性能;
        2) 同时拿不到锁的线程还会进入阻塞状态,
        3) 进而触发线程切换,线程切换对性能的消耗也很大。 
    
    2.相比之下,无锁方案
        1) 完全没有加锁、解锁的性能消耗,
        2)同时还能保证互斥性

    getAndIncrement() 方法内部就是基于 CAS 实现的:

  • 相关阅读:
    [noip2018]day1
    [CF1110d]JONGMAH
    BZOJ 2733 [HNOI2012]永无乡
    BZOJ 3123 [SDOI2013] 森林
    Nowcoder 练习赛26E 树上路径
    Luogu 2575 高手过招-SG函数
    BZOJ 1123[POI2008]BLO-Tarjan
    Nowcoder OI赛制测试2 F 假的数学题
    Luogu 2467[SDOI2010]地精部落
    Luogu 2216[HAOI2007]理想的正方形
  • 原文地址:https://www.cnblogs.com/big-cut-cat/p/13552967.html
Copyright © 2011-2022 走看看