如何判断 AtomicIntegerArray 是否已经初始化
下文笔者讲述AtomicIntegerArray是否初始化的简介说明,如下所示
`AtomicIntegerArray`简介说明
`AtomicIntegerArray` 没有提供原生的 `isInitialized()` 方法,
也不存在内置的状态标记来区分“未初始化”和“已初始化(空数组)”:
- 当通过 `new AtomicIntegerArray(int length)` 创建时,
即使 `length=0`,
也是一个已初始化的空数组(长度固定为0,可正常调用 `length()`、`get()` 等方法,
不会抛出空指针异常);
- 未初始化的本质是:持有 `AtomicIntegerArray` 引用的变量为 `null`
(引用未指向任何实际的原子数组对象)。
因此,判断 `AtomicIntegerArray` 是否初始化,核心是判断其引用是否为 `null`,在此基础上可根据业务需求补充额外判断(如数组长度是否符合预期)。
AtomicIntegerArray是否初始化的判断方法
1.核心逻辑:
优先判断 `AtomicIntegerArray` 引用是否为 `null`,
这是区分“未初始化”和“已初始化”的根本标准;
2.基础方案:
`if (atomicArray == null)` 表示未初始化,
`if (atomicArray != null)` 表示已初始化;
3.进阶方案:
根据业务需求补充校验,如 `array.length() > 0`(排除空数组)、
遍历判断有效数据(排除默认值数组);
4.线程安全:
多线程环境下需结合 `volatile` + 双重检查锁,
避免重复初始化和可见性问题;
5.关键区分:
不要将“长度为0的空数组”误判为“未初始化”,
二者的引用状态和可操作性不同。
例:基础null判断
import java.util.concurrent.atomic.AtomicIntegerArray;
public class AtomicIntegerArrayInitCheckBasic {
// 声明AtomicIntegerArray引用,初始为null(未初始化)
private static AtomicIntegerArray atomicArray;
public static void main(String[] args) {
// 1. 未初始化时,引用为null
if (atomicArray == null) {
System.out.println("AtomicIntegerArray 尚未初始化(引用为null)");
// 执行初始化操作
atomicArray = new AtomicIntegerArray(5); // 初始化长度为5的原子数组
System.out.println("AtomicIntegerArray 已完成初始化");
}
// 2. 初始化后,引用不为null
if (atomicArray != null) {
System.out.println("AtomicIntegerArray 已初始化,数组长度:" + atomicArray.length());
}
}
}
运行结果
AtomicIntegerArray 尚未初始化(引用为null)
AtomicIntegerArray 已完成初始化
AtomicIntegerArray 已初始化,数组长度:5
结合业务场景补充校验
在基础null 判断之上
若业务对“有效初始化”有额外要求(如数组长度不能为0、需包含有效数据等),
可补充后续校验逻辑,形成完整的初始化判断体系。
场景1:
判断是否为“有效初始化”(排除长度为0的空数组)
若业务中不允许初始化长度为0的空数组,可在 null 判断后,补充 `length()` 方法判断数组长度是否大于0。
例:
import java.util.concurrent.atomic.AtomicIntegerArray;
public class AtomicIntegerArrayValidInitCheck {
private static AtomicIntegerArray atomicArray;
public static void main(String[] args) {
// 模拟:初始化一个长度为0的空数组(形式上初始化,实际无有效元素)
atomicArray = new AtomicIntegerArray(0);
// 完整判断:引用非null + 数组长度>0(有效初始化)
if (isValidInitialized(atomicArray)) {
System.out.println("AtomicIntegerArray 已完成有效初始化");
} else {
System.out.println("AtomicIntegerArray 未初始化,或仅初始化为空数组(长度为0)");
// 重新初始化有效数组
atomicArray = new AtomicIntegerArray(new int[]{1, 2, 3});
System.out.println("重新初始化后,是否有效:" + isValidInitialized(atomicArray));
}
}
/
判断AtomicIntegerArray是否为有效初始化
/
private static boolean isValidInitialized(AtomicIntegerArray array) {
// 步骤1:判断引用是否为null(未初始化)
if (array == null) {
return false;
}
// 步骤2:判断数组长度是否大于0(排除空数组)
return array.length() > 0;
}
}
运行结果如下所示:
AtomicIntegerArray 未初始化,或仅初始化为空数组(长度为0)
重新初始化后,是否有效:true
判断是否为“包含有效数据的初始化”(排除默认值数组)
若业务要求数组不仅要初始化,
还需包含非默认值(默认值为0)的有效数据,
可在基础判断后,遍历数组校验元素是否符合预期。
例:
import java.util.concurrent.atomic.AtomicIntegerArray;
public class AtomicIntegerArrayDataInitCheck {
private static AtomicIntegerArray atomicArray;
public static void main(String[] args) {
// 初始化一个默认值数组(所有元素为0)
atomicArray = new AtomicIntegerArray(3);
// 判断是否包含有效数据(非0元素)
if (isInitializedWithValidData(atomicArray)) {
System.out.println("AtomicIntegerArray 已初始化且包含有效数据");
} else {
System.out.println("AtomicIntegerArray 未初始化,或仅包含默认值(无有效数据)");
// 初始化包含有效数据的数组
atomicArray = new AtomicIntegerArray(new int[]{10, 20, 30});
System.out.println("重新初始化后,是否包含有效数据:" + isInitializedWithValidData(atomicArray));
}
}
/
判断AtomicIntegerArray是否初始化且包含有效数据(非0元素)
/
private static boolean isInitializedWithValidData(AtomicIntegerArray array) {
// 步骤1:基础有效初始化判断
if (array == null || array.length() == 0) {
return false;
}
// 步骤2:遍历数组,判断是否存在非默认值(0)的有效元素
for (int i = 0; i < array.length(); i++) {
if (array.get(i) != 0) {
return true; // 存在有效数据,返回true
}
}
return false; // 所有元素均为默认值,无有效数据
}
}
运行结果如下所示:
AtomicIntegerArray 未初始化,或仅包含默认值(无有效数据)
重新初始化后,是否包含有效数据:true
场景3:多线程环境下的安全判断(避免并发初始化问题)
在多线程环境中,
若存在多个线程可能触发初始化操作,
需在判断的同时保证线程安全,避免重复初始化,
可结合 `volatile` 修饰引用 + 双重检查锁(DCL)实现。
例:
import java.util.concurrent.atomic.AtomicIntegerArray;
public class AtomicIntegerArrayThreadSafeInitCheck {
// volatile修饰:保证引用的可见性,避免指令重排导致的半初始化问题
private static volatile AtomicIntegerArray atomicArray;
public static void main(String[] args) throws InterruptedException {
// 启动10个线程,并发判断并初始化
for (int i = 0; i < 10; i++) {
new Thread(() -> {
AtomicIntegerArray array = getInitializedAtomicArray();
System.out.println(Thread.currentThread().getName() + ":获取到已初始化的数组,长度:" + array.length());
}, "线程-" + i).start();
}
}
/
多线程安全的初始化与获取方法(双重检查锁)
/
private static AtomicIntegerArray getInitializedAtomicArray() {
// 第一次检查:快速判断,避免不必要的锁竞争
if (atomicArray == null) {
synchronized (AtomicIntegerArrayThreadSafeInitCheck.class) {
// 第二次检查:确保只有一个线程执行初始化
if (atomicArray == null) {
System.out.println(Thread.currentThread().getName() + ":执行初始化操作");
atomicArray = new AtomicIntegerArray(5);
}
}
}
return atomicArray;
}
}
运行结果(仅一个线程执行初始化)
线程-0:执行初始化操作
线程-0:获取到已初始化的数组,长度:5
线程-1:获取到已初始化的数组,长度:5
线程-2:获取到已初始化的数组,长度:5
...(后续线程均获取到已初始化的数组)
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。


