zoukankan      html  css  js  c++  java
  • AtomicInteger学习

    面试时被问到了,补下

    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;
            }
        }
    
    
    }
  • 相关阅读:
    多线程--ThreadLocal类
    常用开发类库支持--UUID及空值处理Optional
    国际化的程序实现及其原理
    浅析java设计模式(一)----异构容器,可以存储任何对象类型为其他类提供该对象
    使用批处理命令注册运行mysql数据库,无需注册mysql服务,可以在任意电脑登录使用
    计算机中位、字长、字的区别
    SQL Server用户自定义数据类型
    简单的回合制小游戏
    单链表创建、删除、查找、插入之C语言实现
    LeetCode-905 Sort Array By Parity Solution (with Java)
  • 原文地址:https://www.cnblogs.com/mytzq/p/9316186.html
Copyright © 2011-2022 走看看