@[toc]
- 上文我们介绍了Atomic原子类 并且写了 AtomicInteeger 的使用 简单的介绍了底层的实现 CAS
- 本章我们介绍下 AtmoicArray 与 AtmoicReference
Atomic*Array 数组原子类
package com.yxl.modules.controller;
import java.util.concurrent.atomic.AtomicIntegerArray;
/**
* 演示AtomicIntegerArray
*/
public class AtmoicArray {
public static void main(String[] args) throws InterruptedException {
AtomicIntegerArray atomicIntegerArray=new AtomicIntegerArray(1000);
Decrement decrement = new Decrement(atomicIntegerArray);
Increment increment = new Increment(atomicIntegerArray);
Thread[] threads= new Thread[100];
Thread[] threads2= new Thread[100];
for (int i = 0; i < 100 ; i++) {
threads2[i]=new Thread(decrement);
threads[i]=new Thread(increment);
threads2[i].start();
threads[i].start();
}
for (int i = 0; i < 100 ; i++) {
threads2[i].join();
threads[i].join();
}
for (int i = 0; i < atomicIntegerArray.length(); i++) {
if(atomicIntegerArray.get(i)!=0) {
System.out.println("发现非0值" + i);
}
}
System.out.println("运行结束");
}
}
class Decrement implements Runnable{
private AtomicIntegerArray array;
Decrement(AtomicIntegerArray array) {
this.array = array;
}
@Override
public void run() {
for (int i = 0; i < array.length() ; i++) {
array.getAndDecrement(i);
}
}
}
class Increment implements Runnable{
private AtomicIntegerArray array;
Increment(AtomicIntegerArray array) {
this.array = array;
}
@Override
public void run() {
for (int i = 0; i < array.length() ; i++) {
array.getAndIncrement(i);
}
}
}
- 运行结果 ,会发现我们数组线程每次 加100 减100 ,并不会出现不等于0的数据,数据并没有出现错乱,AtomicIntegerArray 给我们提供了数组的原子性
Atomic*Reference 引用类型原子类
Atomic*Reference 和我们之前讲过的 AtomicInether 本质没有任何区别,
AtomicInether 可以让一个整形保证原子性
而AtomicReference可以让对象保证原子性,
AtomicReference的用法肯定要比AtomicInether强,因为它一个对象可以包含多个属性
- 因为他是对象比较比较,所有不会有自增,自减操作,他会进行对象比较
我们看下jdk 方法
把普通变量升级为原子变量
AtomicIntergerfiledUpdateer 对普通变量进行升级
- 代码示例
package com.yxzapp.aspect;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
public class a implements Runnable{
static Persion persion;
static Persion tom;
//AtomicIntegerFieldUpdater的用法
AtomicIntegerFieldUpdater<Persion > atomicIntegerFieldUpdater = AtomicIntegerFieldUpdater.newUpdater(Persion.class,"store");
@Override
public void run() {
for (int i = 0; i < 10000 ; i++) {
persion.store++;
atomicIntegerFieldUpdater.getAndIncrement(tom);
}
}
public static class Persion{
volatile int store;
}
public static void main(String[] args) throws InterruptedException {
persion=new Persion();
tom = new Persion();
a a = new a();
Thread thread = new Thread(a);
Thread thread2 = new Thread(a);
thread.start();
thread2.start();
thread.join();
thread2.join();
System.out.println("tom" + tom.store);
System.out.println("persion " + persion.store);
}
}
- 运行结果
但是使用AtomicIntergerfiledUpdateer 有几点需要注意
- 可见范围
- 不支持static 修饰的变量 否则会出现异常