java程序初始化数据 AtomicBoolean initialized + synchronized

14 阅读2分钟

静态初始化 数据是(死的)

` public class MaterialCache {

public static final Set<String> HIDDEN_MATERIALS;
public static final Set<String> SHOW_MATERIALS;

static {
    // 模拟从数据库或配置加载
    List<OrdConsumeRuleMaterials> list = DatabaseLoader.loadAllMaterials(); // 自定义加载逻辑

    Map<String, List<OrdConsumeRuleMaterials>> groupMap = 
        list.stream().collect(Collectors.groupingBy(OrdConsumeRuleMaterials::getFlag));

    HIDDEN_MATERIALS = groupMap.getOrDefault("hidden", Collections.emptyList())
        .stream().map(OrdConsumeRuleMaterials::getMaterialCode).filter(Objects::nonNull)
        .collect(Collectors.toSet());

    SHOW_MATERIALS = groupMap.getOrDefault("show", Collections.emptyList())
        .stream().map(OrdConsumeRuleMaterials::getMaterialCode).filter(Objects::nonNull)
        .collect(Collectors.toSet());

    System.out.println("✅ 静态缓存初始化完成");
}

// 注意:这个类甚至可以是工具类,没有 @Service

} `

## 启动时初始化(更推荐)

` import javax.annotation.PostConstruct;

@Service public class OrdConsumeRuleMaterialsServiceImpl extends ServiceImpl<...> {

private final Set<String> hiddenMaterialSet = new HashSet<>();
private final Set<String> showMaterialSet = new HashSet<>();

@PostConstruct
public void init() {
    try {
        refreshCache();
        log.info("✅ 缓存初始化完成,hidden={}, show={}", 
                 hiddenMaterialSet.size(), showMaterialSet.size());
    } catch (Exception e) {
        log.error("❌ 缓存初始化失败,将使用空缓存", e);
    }
}

// 不需要 ensureInitialized() 了!
// 后续直接使用 hiddenMaterialSet 和 showMaterialSet

} public void refreshCache() { final List list = this.list(); final Map<String, List> groupMap = list.stream().collect(Collectors.groupingBy(OrdConsumeRuleMaterials::getFlag));

    final Set<String> hiddenSet = groupMap.getOrDefault("hidden", Collections.emptyList())
        .stream().map(OrdConsumeRuleMaterials::getMaterialCode).filter(Objects::nonNull)
        .collect(Collectors.toSet());

    final Set<String> showSet = groupMap.getOrDefault("show", Collections.emptyList())
        .stream().map(OrdConsumeRuleMaterials::getMaterialCode).filter(Objects::nonNull)
        .collect(Collectors.toSet());

    // 原地更新(在单线程中进行)
    hiddenMaterialSet.clear();
    showMaterialSet.clear();
    hiddenMaterialSet.addAll(hiddenSet);
    showMaterialSet.addAll(showSet);
}

// 更新接口
   @ApiOperation("刷新老订单物料展示数据")
@GetMapping("ordMaterialRefresh")
public R<?> ordMaterialRefresh() {
    ordConsumeRuleMaterialsService.refreshCache();

    return R.ok();
}

`

initialized + synchronized

`public class OrdConsumeRuleMaterialsServiceImpl extends ServiceImpl<OrdConsumeRuleMaterialsMapper, OrdConsumeRuleMaterials> implements OrdConsumeRuleMaterialsService { private final Set hiddenMaterialSet = new HashSet<>(); private final Set showMaterialSet = new HashSet<>(); private volatile boolean initialized = false;

private void ensureInitialized() {
    if (!initialized) {
        synchronized (this) {
            if (!initialized) {
                try {
                    refreshCache();
                    initialized = true;
                    log.info("✅ OrdConsumeRuleMaterials 缓存初始化完成,hidden={},show={}", hiddenMaterialSet.size(), showMaterialSet.size());
                } catch (Exception e) {
                    initialized = true;
                    log.error("OrdConsumeRuleMaterials 缓存初始化失败,将使用空缓存:{}",e.getMessage());
                }
            }
        }
    }
}

public void refreshCache() {
    final List<OrdConsumeRuleMaterials> list = this.list();

    final Map<String, List<OrdConsumeRuleMaterials>> groupMap = list.stream().collect(Collectors.groupingBy(OrdConsumeRuleMaterials::getFlag));

    final Set<String> hiddenSet = groupMap.getOrDefault("hidden", Collections.emptyList()).stream().map(OrdConsumeRuleMaterials::getMaterialCode).filter(Objects::nonNull).collect(Collectors.toSet());

    final Set<String> showSet = groupMap.getOrDefault("show", Collections.emptyList()).stream().map(OrdConsumeRuleMaterials::getMaterialCode).filter(Objects::nonNull).collect(Collectors.toSet());

    hiddenMaterialSet.clear();
    showMaterialSet.clear();
    hiddenMaterialSet.addAll(hiddenSet);
    showMaterialSet.addAll(showSet);
}

public boolean isHiddenMaterial(String material) {
    ensureInitialized();
    return material != null && hiddenMaterialSet.contains(material);
}

public boolean isShowMaterial(String material) {
    ensureInitialized();
    return material != null && showMaterialSet.contains(material);
}

`

AtomicBoolean

` private final AtomicBoolean initialized = new AtomicBoolean(false); // ✅ 替代 volatile boolean

private void ensureInitialized() {
    // 如果已经初始化,直接返回
    if (initialized.get()) {
        return;
    }

    // 尝试设置为“正在初始化”,只有第一个线程能成功
    if (initialized.compareAndSet(false, true)) {
        try {
            refreshCache();
            log.info("✅ 缓存初始化完成,hidden={}, show={}", hiddenMaterialSet.size(), showMaterialSet.size());
        } catch (Exception e) {
            log.error("❌ 缓存初始化失败,将使用空缓存", e);
            // 即使失败也标记为“已尝试”,防止无限重试
        }
    }
    // 其他线程走到这里会直接返回,不参与初始化
}

`