java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java原子类属性

Java多线程中的原子类属性说明

作者:ruan_luqingnian

这篇文章主要介绍了Java多线程中的原子类属性说明,对多线程访问同一个变量,我们需要加锁,而锁是比较消耗性能的,JDk1.5之后,新增的原子操作类提供了一种用法简单、性能高效、线程安全地更新一个变量的方式,需要的朋友可以参考下

什么是原子类

什么是原子类

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

为什么要有原子类

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

java8新增原子类

DoubleAccumulator、DoubleAdder、LongAccumulator、LongAdder、Striped64

package 多线程.atomic.demo1;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: ruan
 * Date: 2021/7/4 12:09
 * @Description:
 */
public class Demo1 {
    private static AtomicInteger sum = new AtomicInteger(0);

    public static void inCreat(){
        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++) {
                    inCreat();
                    System.out.println(sum);
                    try {
                        Thread.sleep(200l);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();

        }
    }
}

原子更新基本类型

发展至JDk1.8,基本类型原子类有以下几个:

AtomicBoolean、AtomicInteger、AtomicLong、DoubleAccumulator、DoubleAdder、LongAccumulator、LongAdder

大致可以归为3类

package 多线程.atomic.demo1;

import java.util.concurrent.atomic.LongAccumulator;

/**
 * @Author: ruan
 * Date: 2021/7/4 12:20
 * @Description:
 */
public class Demo2 {
    public static void main(String[] args) {
        LongAccumulator longAccumulator = new LongAccumulator((left,right)->
                left > right ? left : right,0L
                );
        longAccumulator.accumulate(3l);
        System.out.println(longAccumulator.get());
    }
}

原子更新数组类型

AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray

package 多线程.atomic.demo2;

import java.util.concurrent.atomic.AtomicIntegerArray;

/**
 * @Author: ruan
 * Date: 2021/7/4 12:26
 * @Description:
 */
public class Demo1 {
    public static void main(String[] args) {
        int[] arr = new int[]{1,2,3,4,5};
        AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(arr);
        int i = atomicIntegerArray.addAndGet(1, 2);
        System.out.println(i);
        //自定义计算
        int i1 = atomicIntegerArray.accumulateAndGet(0, 2, ((left, right) ->
                left > right ? left : right
        ));

        System.out.println(i1);
    }
}

原子更新属性

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

AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicStampedReference、AtomicReferenceFieldUpdater

使用上述类的时候,必须遵循以下原则

package 多线程.atomic.demo3;

import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

/**
 * @Author: ruan
 * Date: 2021/7/4 12:48
 * @Description:
 */
public class Demo1 {
    public static void main(String[] args) {
        Student student = new Student("ruan", 18L);
        AtomicLongFieldUpdater<Student> longFieldUpdater = AtomicLongFieldUpdater.newUpdater(Student.class, "age");
        longFieldUpdater.compareAndSet(student,18L,20L);
        System.out.println("age = " + student.getAge());
        AtomicReferenceFieldUpdater<Student, String> objectObjectAtomicReferenceFieldUpdater = AtomicReferenceFieldUpdater.newUpdater(Student.class,String.class,"name");
        objectObjectAtomicReferenceFieldUpdater.compareAndSet(student,"ruan","ruanxiangge");
        System.out.println("name = " + student.getName());

    }
}
class Student{
    volatile String name;
    volatile long age;

    public Student(String name, long age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getAge() {
        return age;
    }

    public void setAge(long age) {
        this.age = age;
    }
}

原子更新引用

package 多线程.atomic.demo4;

import java.util.concurrent.atomic.AtomicReference;

/**
 * @Author: ruan
 * Date: 2021/7/4 13:03
 * @Description:
 */
public class Demo1 {
    public static void main(String[] args) {
        AtomicReference<Student> studentAtomicReference = new AtomicReference<>();
        Student ruan = new Student(1L, "ruan");
        Student rxg = new Student(2L, "rxg");
        studentAtomicReference.set(ruan );
        boolean b = studentAtomicReference.compareAndSet(ruan, rxg);
        Student student = studentAtomicReference.get();
        System.out.println(student.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;
    }
}

到此这篇关于Java多线程中的原子类属性说明的文章就介绍到这了,更多相关Java原子类属性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文