zoukankan      html  css  js  c++  java
  • AtomicInteger的并发处理

    JDK1.5之后的java.util.concurrent.atomic包里,多了一批原子处理类。主要用于在高并发环境下的高效程序处理。

    网上关于这个原理介绍的比较靠谱的一片文章是出自IBM工程师的一篇:

    流行的原子

    值得一看。

    这里,我们来看看AtomicInteger是如何使用非阻塞算法来实现并发控制的。

    AtomicInteger的关键域只有一下3个:

    Java代码  收藏代码
    1. // setup to use Unsafe.compareAndSwapInt for updates  
    2. private static final Unsafe unsafe = Unsafe.getUnsafe();  
    3. private static final long valueOffset;  
    4. private volatile int value;  

     这里, unsafe是java提供的获得对对象内存地址访问的类,注释已经清楚的写出了,它的作用就是在更新操作时提供“比较并替换”的作用。实际上就是AtomicInteger中的一个工具。

    valueOffset是用来记录value本身在内存的便宜地址的,这个记录,也主要是为了在更新操作在内存中找到value的位置,方便比较。

    注意:value是用来存储整数的时间变量,这里被声明为volatile,就是为了保证在更新操作时,当前线程可以拿到value最新的值(并发环境下,value可能已经被其他线程更新了)。

    这里,我们以自增的代码为例,可以看到这个并发控制的核心算法:

    Java代码  收藏代码
    1.    /** 
    2.     * Atomically increments by one the current value. 
    3.     * 
    4.     * @return the updated value 
    5.     */  
    6.    public final int incrementAndGet() {  
    7.        for (;;) {  
    8.            //这里可以拿到value的最新值  
    9.            int current = get();  
    10.            int next = current + 1;  
    11.            if (compareAndSet(current, next))  
    12.                return next;  
    13.        }  
    14.    }  
    15.   
    16.    public final boolean compareAndSet(int expect, int update) {  
    17.        //使用unsafe的native方法,实现高效的硬件级别CAS  
    18. return unsafe.compareAndSwapInt(this, valueOffset, expect, update);  
    19.    }  

     好了,看到这个代码,基本上就看到这个类的核心了。相对来说,其实这个类还是比较简单的。

    看到网上一些资料对这个类的一些问题,这里简要摘录几个关键的,尝试解答一下:

    1、为什么AtomicInteger里面的compareAndSet和weakCompareAndSet方法实现完全一样,注释说明却不同?

    这个问题,一个老外的回答比较靠谱,这里给出链接:the difference between compareAndSet and weakCompareAndSet 。核心观点就是人家保留更改这个实现的权利。现在一样可能是暂时的,将来可能会不一样,所以使用接口时,还是按照人家接口说明来吧。

    2、他比直接使用传统的java锁机制(阻塞的)有什么好处?

    最大的好处就是可以避免多线程的优先级倒置和死锁情况的发生,当然高并发下的性能提升也是很重要的。

    3、使用了他,并发环境下就一定没问题了吗?

    这个还真未必!这个在上面那篇《流行的原子》文章中也提到了的ABA问题。在某些场景下,可能会造成业务问题。但是多数的场景(比如高效的计数器实现)是不用担心这个问题的。

  • 相关阅读:
    ubuntu远程windows桌面
    spring boot 给返回值加状态 BaseData
    spring boot 拦截异常 统一处理
    IntelliJ IDEA spring boot 远程Ddbug调试
    IntelliJ IDEA 常用插件
    spring boot 请求地址带有.json 兼容处理
    spring boot 接口返回值去掉为null的字段
    spring boot 集成disconf
    Spring boot 自定义拦截器
    Linux下安装MySQL
  • 原文地址:https://www.cnblogs.com/wzhanke/p/4486216.html
Copyright © 2011-2022 走看看