静态初始化 数据是(死的)
` 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);
// 即使失败也标记为“已尝试”,防止无限重试
}
}
// 其他线程走到这里会直接返回,不参与初始化
}
`