zoukankan      html  css  js  c++  java
  • 并发编程中的原子类

    1.什么是原子类

    一度认为原子是不可分割的最小单位,故原子类可以认为其操作都是不可分割

    1.1 为什么要有原子类?

    对多线程访问同一个变量,我们需要加锁,而锁是比较消耗性能的,JDk1.5之后, 新增的原子操作类提供了
    一种用法简单、性能高效、线程安全地更新一个变量的方式, 这些类同样位于JUC包下的atomic包下,发展
    到JDk1.8,该包下共有17个类, 囊括了原子更新基本类型、原子更新数组、原子更新属性、原子更新引用

    1.2 1.8新增的原子类

    DoubleAccumulator、DoubleAdder、LongAccumulator、LongAdder、Striped64

    2.原子更新基本类型

    发展至JDk1.8,基本类型原子类有以下几个:
    AtomicBoolean、AtomicInteger、AtomicLong、DoubleAccumulator、DoubleAdder、LongAccumulator、
    LongAdder
    大致可以归为3类
    AtomicBoolean、AtomicInteger、AtomicLong 元老级的原子更新,方法几乎一模一样 DoubleAdder、
    LongAdder 对Double、Long的原子更新性能进行优化提升 DoubleAccumulator、LongAccumulator 支持自定
    义运算

    /**
     * atomicInteger Demo
     */
    public class Demo1 {
    
        private static AtomicInteger sum = new AtomicInteger(0);
    
        public static void inCreate() {
    
            sum.incrementAndGet();
    
    
        }
    
    
        public static void main(String[] args) throws InterruptedException {
    
    
            for (int i = 0; i < 10; i++) {
                new Thread(()->{
    
                    for (int j = 0; j < 100; j++) {
                        inCreate();
                        System.out.println(sum);
                    }
                }).start();
    
            }
    
        }
    }
    
    LongAccumulator Demo自定义运算
    /**
     * LongAccumulator Demo
     * 自定义运算
     */
    public class Demo2 {
    
    
        public static void main(String[] args) {
    
            //输入一个数字,如果比上一个输入的大,则直接返回
            //如果小则返回上一个
            LongAccumulator longAccumulator =
                    new LongAccumulator((left, right) ->
    
    //                    left > right ? left : right,
                        left+right ,
                            0L
                    );
            longAccumulator.accumulate(3L);
            System.out.println(longAccumulator.get());
            longAccumulator.accumulate(5L);
            System.out.println(longAccumulator.get());
        }
    }
    

    3.原子更新数组类型

    AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray

    /**
     * AtomicIntegerArry  Demo
     */
    public class AtomicIntegerArryDemo {
    
        public static void main(String[] args) {
    
            int[] arr = new int[]{3, 2};
    
            AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(arr);
    
            //下标和步长
            int i = atomicIntegerArray.addAndGet(1, 8);
            int j = atomicIntegerArray.addAndGet(0, 8);
    
            System.out.println("i:" + i + "--j:" + j);
    
            System.out.println(  atomicIntegerArray.toString());
    
            //自定义运算
            /**
             *下标
             * 把下标的值更新为20
             * 相关的运算
             */
            int k = atomicIntegerArray.accumulateAndGet(
                    0, 20, (left, right) ->
                            left >right?left:right
            );
            System.out.println(  atomicIntegerArray.toString());
            System.out.println("k->"+k);
    
        }
    }
    

    4.原子地更新属性

    原子地更新某个类里的某个字段时,就需要使用原子更新字段类,Atomic包提供了以下4个类进行原子字段更新
    AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicStampedReference、AtomicReferenceFieldUpdater

    /**
     * AtomicLongFieldUpdateDemo
     */
    public class AtomicLongFieldUpdaterDemo {
    
        static class Student {
    
            volatile long id;
            volatile String name;
    
            public Student(long id, String name) {
                this.id = id;
                this.name = name;
            }
    
            public long getId() {
                return id;
            }
    
            public void setId(long id) {
                this.id = id;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
        }
    
    
        public static void main(String[] args) {
            AtomicLongFieldUpdater<Student> longFieldUpdater = AtomicLongFieldUpdater.newUpdater(Student.class, "id");
    
            Student testStu = new Student(1L, "test");
            longFieldUpdater.compareAndSet(testStu, 1L, 100L);
    
            System.out.println("id=" + testStu.getId());
    
            AtomicReferenceFieldUpdater<Student, String> referenceFieldUpdater = AtomicReferenceFieldUpdater.newUpdater(Student.class, String.class, "name");
    
            referenceFieldUpdater.compareAndSet(testStu, "test", "update");
            System.out.println("name=" + testStu.getName());
    
        }
    
    }
    
    

    5.原子更新引用

    AtomicReference:用于对引用的原子更新
    AtomicMarkableReference:带版本戳的原子引用类型,版本戳为boolean类型。
    AtomicStampedReference:带版本戳的原子引用类型,版本戳为int类型。

    public class AtomicReferenceDemo {
    
        public static void main(String[] args) {
            AtomicReference<Student> studentAtomicReference = new AtomicReference<>();
    
            Student stuTest01 = new Student(1L, "test01");
            Student stuTest02 = new Student(2L, "test02");
            //先设置值
            studentAtomicReference.set(stuTest01);
            studentAtomicReference.compareAndSet(stuTest01,stuTest02);
            //再得到更新值
            Student studentUpd = studentAtomicReference.get();
            System.out.println(studentUpd.getName());
    
    
        }
    
    
    }
    
    class Student{
    
        private long id;
        private String name;
    
        public Student(long id, String name) {
            this.id = id;
            this.name = name;
        }
    
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
  • 相关阅读:
    poj 3666 Making the Grade
    poj 3186 Treats for the Cows (区间dp)
    hdu 1074 Doing Homework(状压)
    CodeForces 489C Given Length and Sum of Digits...
    CodeForces 163A Substring and Subsequence
    CodeForces 366C Dima and Salad
    CodeForces 180C Letter
    CodeForces
    hdu 2859 Phalanx
    socket接收大数据流
  • 原文地址:https://www.cnblogs.com/charlypage/p/10890501.html
Copyright © 2011-2022 走看看