package org.kne.concurrent; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; /** * 惰性计算器:只在输入变化且输出被需要时重算。 * * 使用场景:路由表重算、统计信息聚合、UI 数据更新等 * * @param 输出类型 */ public class LazyEvaluator { private final Supplier recomputeFn; // 重算函数(可能较重) private final AtomicBoolean dirty = new AtomicBoolean(true); // true表示需要重算 private volatile T cachedResult; // 缓存结果(volatile保证可见性) /** * @param recomputeFn 当真正需要重算时,调用此函数生成新值 */ public LazyEvaluator(Supplier recomputeFn) { this.recomputeFn = recomputeFn; } /** * 标记输入已变化(每次变化都调用) * CAS 保证多线程下只有一个线程真正置脏,避免无谓的竞争 */ public boolean markDirty() { return dirty.compareAndSet(false, true); } /** * 获取当前值(如果 dirty 且被需要,则触发重算) * 这个方法由需要输出的地方(如 UI 线程、路由引擎)调用 */ public T get() { if (dirty.get()) { synchronized (this) { // double-check:防止多个线程同时进入重算 if (dirty.get()) { cachedResult = recomputeFn.get(); dirty.set(false); } } } return cachedResult; } /** * 获取当前缓存的值(不触发重算) * 适合那些“如果已经算好就直接用,否则也不强求”的场景 */ public T getCached() { return cachedResult; } /** * 当前是否需要重算 */ public boolean isDirty() { return dirty.get(); } }