原子类
原子类
我们进行了分类
基本类型原子类
案例
50 个线程去加 100 次
输出的结果会小于等于 50000
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerDemo {
public static final int SIZE_=50;
public static void main(String[] args) {
MyNumber myNumber = new MyNumber();
for(int i=1;i<=SIZE_;i++){
new Thread(()->{
for (int i1 = 0; i1 < 100; i1++) {
myNumber.addPlusPlus();
}
},String.valueOf(i)).start();
}
System.out.println(myNumber.number);
}
}
// 资源类
class MyAtomicNumber{
AtomicInteger atomicInteger=new AtomicInteger();
public void addPlusPlus(){
atomicInteger.incrementAndGet();
}
}
输出
因为 main 线程太快了
还没算完
等所有线程执行结束再执行 main 线程
CountDownLatch 类阻塞
countDownLatch 会等线程完成一个后自减
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicIntegerDemo {
public static final int SIZE_=50;
public static void main(String[] args) throws InterruptedException {
MyNumber myNumber = new MyNumber();
CountDownLatch countDownLatch = new CountDownLatch(SIZE_);
for(int i=1;i<=SIZE_;i++){
new Thread(()->{
try {
for (int i1 = 0; i1 < 100; i1++) {
myNumber.addPlusPlus();
}
}catch (Exception e){
e.printStackTrace();
}finally {
countDownLatch.countDown();
}
},String.valueOf(i)).start();
}
countDownLatch.await();
// 因为 main 线程太快了 会提前进入
System.out.println(myNumber.number);
}
}
// 资源类
class MyAtomicNumber{
AtomicInteger atomicInteger=new AtomicInteger();
public void addPlusPlus(){
atomicInteger.incrementAndGet();
}
}
相当于一个阻塞效果
敲了一个
代码
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
public class AtomicIntegerArrayDemo {
public static void main(String[] args) {
// 定义原子整型类型的数据
AtomicInteger atomicInteger1 = new AtomicInteger(1);
AtomicInteger atomicInteger2 = new AtomicInteger(2);
AtomicInteger atomicInteger3 = new AtomicInteger(3);
// 原子整型的数据 数组
// AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(new int[]{1, 2, 3});
// 创建一个长度为5的AtomicIntegerArray,初始值都为0
AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(new int[5]);
// 打印数组初始值
for (int i = 0; i < atomicIntegerArray.length(); i++) {
System.out.println(atomicIntegerArray.get(i));
}
int tmpInt = 0;
// 将数组中索引为0的元素设置为1122,并返回原来的值
tmpInt = atomicIntegerArray.getAndSet(0, 1122);
System.out.println(tmpInt + "\t" + atomicIntegerArray.get(0));
// 对数组中索引为1的元素进行自增操作
atomicIntegerArray.getAndIncrement(1);
atomicIntegerArray.getAndIncrement(1);
// 对数组中索引为1的元素进行自增操作,并返回原来的值
tmpInt = atomicIntegerArray.getAndIncrement(1);
System.out.println(tmpInt + "\t" + atomicIntegerArray.get(1));
}
}
}
AtomicIntegerArray
类是 Java 并发包(java.util.concurrent.atomic
)中的一个类,它提供了一种线程安全的方式来操作整数数组。与普通的整数数组不同,AtomicIntegerArray
提供的方法可以确保在多线程环境下的操作是原子的,即不会发生数据竞争或不一致的问题。
下面是一些关于 AtomicIntegerArray
类的相关代码示例及其解释:
创建 AtomicIntegerArray
你可以通过以下几种方式创建 AtomicIntegerArray
实例:
- 使用已有的整数数组:
java
复制
int[] array = {1, 2, 3, 4, 5};
AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(array);
- 指定数组长度,所有元素初始化为0:
java
复制
AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(5);
- 使用已有的整数数组并复制该数组:
java
复制
int[] array = {1, 2, 3, 4, 5};
AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(array.clone());
基本操作
AtomicIntegerArray
提供了一些基本的操作方法,如获取、设置、自增、自减等。以下是一些常见的操作示例:
- 获取指定索引处的值:
java
复制
int value = atomicIntegerArray.get(0);
System.out.println("Value at index 0: " + value);
- 设置指定索引处的值:
java
复制
atomicIntegerArray.set(0, 10);
System.out.println("New value at index 0: " + atomicIntegerArray.get(0));
- 原子地设置指定索引处的值,并返回旧值:
java
复制
int oldValue = atomicIntegerArray.getAndSet(0, 20);
System.out.println("Old value at index 0: " + oldValue);
- 原子地自增指定索引处的值:
java
复制
int incrementedValue = atomicIntegerArray.getAndIncrement(1);
System.out.println("Incremented value at index 1: " + incrementedValue);
- 原子地自减指定索引处的值:
java
复制
int decrementedValue = atomicIntegerArray.getAndDecrement(1);
System.out.println("Decremented value at index 1: " + decrementedValue);
- 原子地增加指定索引处的值,并返回旧值:
java
复制
int addedValue = atomicIntegerArray.getAndAdd(1, 5);
System.out.println("Added value at index 1: " + addedValue);
CAS 操作
AtomicIntegerArray
还提供了一些基于比较并交换(Compare and Swap, CAS)的操作,这些操作可以确保在多线程环境下的原子性:
- 原子地设置指定索引处的值,只有当当前值等于预期值时才设置成功:
java
复制
boolean isSet = atomicIntegerArray.compareAndSet(0, 20, 30);
System.out.println("Is set successful: " + isSet);
完整示例
以下是一个完整的示例,展示了如何使用 AtomicIntegerArray
类的各种方法:
java
复制
import java.util.concurrent.atomic.AtomicIntegerArray;
public class AtomicIntegerArrayExample {
public static void main(String[] args) {
// 创建一个长度为5的AtomicIntegerArray,初始值都为0
AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(5);
// 打印数组初始值
for (int i = 0; i < atomicIntegerArray.length(); i++) {
System.out.println("Initial value at index " + i + ": " + atomicIntegerArray.get(i));
}
// 设置指定索引处的值
atomicIntegerArray.set(0, 10);
System.out.println("New value at index 0: " + atomicIntegerArray.get(0));
// 原子地设置指定索引处的值,并返回旧值
int oldValue = atomicIntegerArray.getAndSet(0, 20);
System.out.println("Old value at index 0: " + oldValue);
// 原子地自增指定索引处的值
int incrementedValue = atomicIntegerArray.getAndIncrement(1);
System.out.println("Incremented value at index 1: " + incrementedValue);
// 原子地自减指定索引处的值
int decrementedValue = atomicIntegerArray.getAndDecrement(1);
System.out.println("Decremented value at index 1: " + decrementedValue);
// 原子地增加指定索引处的值,并返回旧值
int addedValue = atomicIntegerArray.getAndAdd(1, 5);
System.out.println("Added value at index 1: " + addedValue);
// 原子地设置指定索引处的值,只有当当前值等于预期值时才设置成功
boolean isSet = atomicIntegerArray.compareAndSet(0, 20, 30);
System.out.println("Is set successful: " + isSet);
}
}
通过这些示例,你可以看到 AtomicIntegerArray
类在多线程环境下的强大功能,它可以确保对数组的操作是原子的,从而避免数据竞争和不一致的问题。