当前位置: 代码迷 >> Java相关 >> 第10一章 AtomicInteger源码解析
  详细解决方案

第10一章 AtomicInteger源码解析

热度:57   发布时间:2016-04-22 19:21:03.0
第十一章 AtomicInteger源码解析

1、原子类

  • 可以实现一些原子操作
  • 基于CAS

下面就以AtomicInteger为例。

 

2、AtomicInteger

在没有AtomicInteger之前,对于一个Integer的线程安全操作,是需要使用同步锁来实现的,当然现在也可以通过ReentrantLock来实现,但是最好最方便的实现方式是采用AtomicInteger。

具体示例:

package com.collection.test;import java.util.concurrent.atomic.AtomicInteger;/** * 原子类的测试 */public class AtomicTest {    private static AtomicInteger atomicInteger = new AtomicInteger();        //获取当前值    public static void getCurrentValue(){        System.out.println(atomicInteger.get());//-->0    }        //设置value值    public static void setValue(){        atomicInteger.set(12);//直接用12覆盖旧值        System.out.println(atomicInteger.get());//-->12    }        //根据方法名称getAndSet就知道先get,则最后返回的就是旧值,如果get在后,就是返回新值    public static void getAndSet(){        System.out.println(atomicInteger.getAndSet(15));//-->12    }        public static void getAndIncrement(){        System.out.println(atomicInteger.getAndIncrement());//-->15    }        public static void getAndDecrement(){        System.out.println(atomicInteger.getAndDecrement());//-->16    }        public static void getAndAdd(){        System.out.println(atomicInteger.getAndAdd(10));//-->15    }        public static void incrementAndGet(){        System.out.println(atomicInteger.incrementAndGet());//-->26    }        public static void decrementAndGet(){        System.out.println(atomicInteger.decrementAndGet());//-->25    }        public static void addAndGet(){        System.out.println(atomicInteger.addAndGet(20));//-->45    }        public static void main(String[] args) {        AtomicTest test = new AtomicTest();        test.getCurrentValue();        test.setValue();        //返回旧值系列        test.getAndSet();        test.getAndIncrement();        test.getAndDecrement();        test.getAndAdd();        //返回新值系列        test.incrementAndGet();        test.decrementAndGet();        test.addAndGet();            }}
View Code

源代码:

    private volatile int value;// 初始化值    /**     * 创建一个AtomicInteger,初始值value为initialValue     */    public AtomicInteger(int initialValue) {        value = initialValue;    }    /**     * 创建一个AtomicInteger,初始值value为0     */    public AtomicInteger() {    }    /**     * 返回value     */    public final int get() {        return value;    }    /**     * 为value设值(基于value),而其他操作是基于旧值<--get()     */    public final void set(int newValue) {        value = newValue;    }    public final boolean compareAndSet(int expect, int update) {        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);    }        /**     * 基于CAS为旧值设定新值,采用无限循环,直到设置成功为止     *      * @return 返回旧值     */    public final int getAndSet(int newValue) {        for (;;) {            int current = get();// 获取当前值(旧值)            if (compareAndSet(current, newValue))// CAS新值替代旧值                return current;// 返回旧值        }    }    /**     * 当前值+1,采用无限循环,直到+1成功为止     * @return the previous value 返回旧值     */    public final int getAndIncrement() {        for (;;) {            int current = get();//获取当前值            int next = current + 1;//当前值+1            if (compareAndSet(current, next))//基于CAS赋值                return current;        }    }    /**     * 当前值-1,采用无限循环,直到-1成功为止      * @return the previous value 返回旧值     */    public final int getAndDecrement() {        for (;;) {            int current = get();            int next = current - 1;            if (compareAndSet(current, next))                return current;        }    }    /**     * 当前值+delta,采用无限循环,直到+delta成功为止      * @return the previous value  返回旧值     */    public final int getAndAdd(int delta) {        for (;;) {            int current = get();            int next = current + delta;            if (compareAndSet(current, next))                return current;        }    }    /**     * 当前值+1, 采用无限循环,直到+1成功为止     * @return the updated value 返回新值     */    public final int incrementAndGet() {        for (;;) {            int current = get();            int next = current + 1;            if (compareAndSet(current, next))                return next;//返回新值        }    }    /**     * 当前值-1, 采用无限循环,直到-1成功为止      * @return the updated value 返回新值     */    public final int decrementAndGet() {        for (;;) {            int current = get();            int next = current - 1;            if (compareAndSet(current, next))                return next;//返回新值        }    }    /**     * 当前值+delta,采用无限循环,直到+delta成功为止       * @return the updated value 返回新值     */    public final int addAndGet(int delta) {        for (;;) {            int current = get();            int next = current + delta;            if (compareAndSet(current, next))                return next;//返回新值        }    }    /**     * 获取当前值     */    public int intValue() {        return get();    }
View Code

说明:使用与源代码都简单到爆了!自己看看注释。

注意:

  • value是volatile的,关于volatile的相关内容见《附2 volatile》,具体链接:http://www.cnblogs.com/java-zhao/p/5125698.html
  • 单步操作:例如set()是直接对value进行操作的,不需要CAS,因为单步操作就是原子操作。
  • 多步操作:例如getAndSet(int newValue)是两步操作-->先获取值,在设置值,所以需要原子化,这里采用CAS实现。
  • 对于方法是返回旧值还是新值,直接看方法是以get开头(返回旧值)还是get结尾(返回新值)就好
  • CAS:比较CPU内存上的值是不是当前值current,如果是就换成新值update,如果不是,说明获取值之后到设置值之前,该值已经被别人先一步设置过了,此时如果自己再设置值的话,需要在别人修改后的值的基础上去操作,否则就会覆盖别人的修改,所以这个时候会直接返回false,再进行无限循环,重新获取当前值,然后再基于CAS进行加减操作。
  • 如果还是不懂CAS,类比数据库的乐观锁