(1)原子类简介
(2)为什么要有原子类
(3)JDK1.8新增的原子类
JDK1.8基本类型原子类有以下分类
AtomicInteger的常见用法
案例实战
public class Demo1 {
private static Integer num = 0;
void addUnSafe(){
//对atomicInteger进行++操作
num++;
}
public static void main(String[] args) throws InterruptedException {
Demo1 demo1 = new Demo1();
new Thread(()->{
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 1000; j++) {
demo1.addUnSafe();
}
}
}).start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 1000; j++) {
demo1.addUnSafe();
}
}
}).start();
Thread.sleep(2000L);
System.out.println("num最后的值:"+num);
}

public class Demo1 {
private static AtomicInteger atomicInteger = new AtomicInteger(0);
void addSafe(){
//对atomicInteger进行++操作
atomicInteger.incrementAndGet();
}
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 1000; j++) {
demo1.addSafe();
}
}
}).start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 1000; j++) {
demo1.addSafe();
}
}
}).start();
Thread.sleep(2000L);
System.out.println("atomicInteger最后的值:"+atomicInteger.get());
}
}

LongAccumulator的简单使用
public class Demo2 {
private static LongAccumulator longAccumulator = new LongAccumulator((x,y) -> x*y,3L);
public static void main(String[] args) {
longAccumulator.accumulate(2);
System.out.println(longAccumulator.get());
}
}

public class Demo1 {
public static void main(String[] args) {
int[] arrInt = new int[]{2,3,4};
AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(arrInt);
//给数组下标是1的元素+2
int i = atomicIntegerArray.addAndGet(1, 2);
System.out.println(i);
//支持自定义规则的操作
int i1 = atomicIntegerArray.accumulateAndGet(1, 2, (x, y) -> x > y ? x : y);
System.out.println(i1);
}
}

(1)原子的更新某个类的某个字段时,就需要使用原子更新字段类,Atomic包提供了一下4个类进行原子字段更新。
(2)AtomicReferenceFieldUpdater、AtomicLongFieldUpdater案例实战
public class Demo2 {
public static void main(String[] args) {
Student student = new Student(1L,"李祥");
//对long类型的数值改变
AtomicLongFieldUpdater<Student> atomicLongFieldUpdater = AtomicLongFieldUpdater.newUpdater(Student.class,"id");
//将Student的id改成10
atomicLongFieldUpdater.compareAndSet(student,1L,10L);
//输出student的id
System.out.println("更改student的id:"+student.id);
//对引用类型的改变
AtomicReferenceFieldUpdater<Student, String> referenceFieldUpdater = AtomicReferenceFieldUpdater.newUpdater(Student.class, String.class, "name");
referenceFieldUpdater.compareAndSet(student,student.getName(),"李祥更改");
System.out.println("更改student的name:"+student.name);
}
}
public 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;
}
}

(3)AtomicStampedReference使用

public class ABADemo {
private static AtomicInteger index = new AtomicInteger(10);
public static void main(String[] args) {
new Thread(()->{
index.compareAndSet(10,11);
index.compareAndSet(11,10);
System.out.println(Thread.currentThread().getName()+": 进行了 10->11->10");
},"张三").start();
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(2);
boolean flag = index.compareAndSet(10, 12);
System.out.println(Thread.currentThread().getName()+":修改index结果:"+flag+",设置的新值是:"+index);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"李祥").start();
}
}

public class AtomicStampedReferenceDemo {
private static AtomicInteger index = new AtomicInteger(10);
private static AtomicStampedReference<Integer> stampedReference = new AtomicStampedReference(10,1);
public static void main(String[] args) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+":当前版本号为:"+stampedReference.getStamp());
stampedReference.compareAndSet(10,11,stampedReference.getStamp(),stampedReference.getStamp()+1);
System.out.println(Thread.currentThread().getName()+":当前版本号为:"+stampedReference.getStamp());
stampedReference.compareAndSet(11,10,stampedReference.getStamp(),stampedReference.getStamp()+1);
System.out.println(Thread.currentThread().getName()+":当前版本号为:"+stampedReference.getStamp());
},"张三").start();
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName()+":拿到的版本号为:"+stampedReference.getStamp());
boolean flag = stampedReference.compareAndSet(10, 12, stampedReference.getStamp(), stampedReference.getStamp() + 1);
System.out.println(Thread.currentThread().getName()+":修改index结果:"+flag+",设置的新值是:"+stampedReference.getReference());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"李祥").start();
}
}
