继续潜水

导航

 

面试时被问到了,补下

 

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by tzq on 2018/7/15.
 */
public class TestAtomic {

    /**
     * @param java中的原子操作类AtomicInteger
     * @author yangcq
     *
     * 关于AtomicInteger的说明(来自官方文档注解)
     * /**
     * An {@code int} value that may be updated atomically.  See the
     * {@link java.util.concurrent.atomic} package specification for
     * description of the properties of atomic variables. An
     * {@code AtomicInteger} is used in applications such as atomically
     * incremented counters, and cannot be used as a replacement for an
     * {@link java.lang.Integer}. However, this class does extend
     * {@code Number} to allow uniform access by tools and utilities that
     * deal with numerically-based classes.
     *
     * @since 1.5
     * @author Doug Lea
     */
    public static void main(String[] args) {
        // 初始值为1
        AtomicInteger atomicInteger = new AtomicInteger(1);
        System.out.println("--初始值atomicInteger = " + atomicInteger);

        // 以原子方式将当前值加1,注意这里返回的是自增前的值
        System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.getAndIncrement());
        System.out.println("--自增后的 atomicInteger = " + atomicInteger);

        // 以原子方式将当前值减1,注意这里返回的是自减前的值
        System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.decrementAndGet());
        System.out.println("--自减后的 atomicInteger = " + atomicInteger);

        // 以原子方式将当前值与括号中的值相加,并返回结果
        System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.addAndGet(11));
        System.out.println("--自增后的 atomicInteger = " + atomicInteger);

        // 如果输入的值等于预期的值,则以原子方式将该值设置成括号中的值
        //atomicInteger等于第一个参数返回true 并将第二个参数赋值
        System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.compareAndSet(12, 2));
        System.out.println("--自减后的 atomicInteger = " + atomicInteger);
        System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.compareAndSet(10, 9999));
        System.out.println("--自减后的 atomicInteger = " + atomicInteger);

        /**
         * 一,AtomicInteger 是如何实现原子操作的呢?
         *
         * 我们先来看一下getAndIncrement的源代码:
         *    public final int getAndIncrement() {
         *        for (;;) {
         *              int current = get();  // 取得AtomicInteger里存储的数值
         *            int next = current + 1;  // 加1
         *            if (compareAndSet(current, next))   // 调用compareAndSet执行原子更新操作
         *                return current;
         *        }
         *    }
         *
         * 这段代码写的很巧妙:
         * 1,compareAndSet方法首先判断当前值是否等于current;
         * 2,如果当前值 = current ,说明AtomicInteger的值没有被其他线程修改;
         * 3,如果当前值 != current,说明AtomicInteger的值被其他线程修改了,这时会再次进入循环重新比较;
         *
         * 注意这里的compareAndSet方法,源代码如下:
         * public final boolean compareAndSet(int expect, int update) {
         *     return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
         * }
         *
         * 调用Unsafe来实现
         * private static final Unsafe unsafe = Unsafe.getUnsafe();
         *
         * 二,java提供的原子操作可以原子更新的基本类型有以下三个:
         *
         * 1,AtomicBoolean
         * 2,AtomicInteger
         * 3,AtomicLong
         *
         * 三,java提供的原子操作,还可以原子更新以下类型的值:
         *
         * 1,原子更新数组,Atomic包提供了以下几个类:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray
         * 2,原子更新引用类型,也就是更新实体类的值,比如AtomicReference<User>
         * AtomicReference:原子更新引用类型的值
         * AtomicReferenceFieldUpdater:原子更新引用类型里的字段
         * AtomicMarkableReference:原子更新带有标记位的引用类型
         * 3,原子更新字段值
         * AtomicIntegerFieldUpdater:原子更新整形的字段的更新器
         * AtomicLongFieldUpdater:原子更新长整形的字段的更新器
         * AtomicStampedReference:原子更新带有版本号的引用类型的更新器
         *
         *
         */
    }

}

四,AtomicIntegerFieldUpdater:原子更新整形的字段的更新器

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
 * Created by tzq on 2018/7/16.
 */
public class Test_AtomicIntegerFieldUpdater {



    /**
     * @param AtomicIntegerFieldUpdater:原子更新整形的字段的更新器
     * @author yangcq
     */

    // 创建原子更新器,并设置需要更新的对象类和对象的属性
    private static AtomicIntegerFieldUpdater<User> atomicIntegerFieldUpdater
            = AtomicIntegerFieldUpdater.newUpdater(User.class, "age1");

    public static void main(String[] args) {

        // 设置age的初始值为1000
        User user = new User();
        user.setUserName("yangcq");
        user.setAge(1000);
        user.setAge1(500);

        // 原子更新引用数据类型的字段值
        System.out.println(atomicIntegerFieldUpdater.getAndIncrement(user));
        // 更新以后的值
        System.out.println(atomicIntegerFieldUpdater.get(user));
        System.out.println(user.getAge());
        System.out.println(user.getAge1());
    }

    //实体类User
    public static class User{
        private String userName;
        public volatile int age;
        public volatile int age1;

        // setter、getter方法
        public String getUserName() {
            return userName;
        }
        public void setUserName(String userName) {
            this.userName = userName;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }

        public int getAge1() {
            return age1;
        }

        public void setAge1(int age1) {
            this.age1 = age1;
        }
    }


}

 

posted on 2018-07-16 09:50  继续潜水  阅读(255)  评论(0编辑  收藏  举报