初学者自定义高并发控制类时易忽视可见性红线:重写接口方法漏加public导致调用失败,辅助方法和字段未显式声明public引发跨包访问中断,构造器非public致spring无法实例化,测试同包掩盖问题,生产环境才暴露限流失效、监控缺失等故障。

初学者在自定义高并发控制类继承抽象类时容易忽视可见性红线,核心在于:抽象类不强制子类补全访问修饰符,而高并发场景对方法和字段的可见性要求极为严格——缺一个 public,就可能让线程安全机制彻底失效。
重写关键方法漏加 public,容器或框架调用直接静默失败
高并发控制类(如继承 AbstractRateLimiter、AbstractSemaphoreWrapper 或自定义限流/信号量骨架)通常需实现接口契约方法(如 tryAcquire()、release()),这些方法在接口中本就是 public。但若子类重写时只写:
-
void tryAcquire() { ... }→ 实际是包级方法,跨包调用时被 JVM 拒绝访问; -
@Override protected void doCleanup() { ... }→ 违反接口契约,外部无法触发清理逻辑; - Spring AOP 或动态代理(如基于 JDK Proxy)仅能代理 public 方法,非 public 方法无法被拦截增强。
结果不是编译报错,而是运行时调用跳过、限流失效、资源泄漏,问题难以复现且日志无提示。
新增并发工具方法默认包级,跨模块调用即断链
为支持高并发,常需添加辅助方法:如 getActiveCount()、isOverloaded()、forceReset()。初学者易忽略修饰符:
- 未声明
public int getActiveCount(),只写int getActiveCount()→ 默认包可见,监控模块、运维 SDK 无法读取状态; - 将
AtomicInteger currentTokens声明为private却未提供 public getter → 外部无法审计令牌余量,熔断策略形同虚设; - 使用 Lombok 的
@Data生成 getter/setter,但字段本身非 public,getter 仍是包级 —— 不解决根本问题。
构造器与核心字段初始化未显式公开,实例化即崩溃
高并发类往往依赖精确初始化(如锁、原子计数器、滑动窗口数组)。常见疏忽:
- 构造器未加
public(如MyRateLimiter(int capacity)),导致 Spring 容器无法反射创建 Bean; - 字段初始化写成局部变量:
ReentrantLock lock = new ReentrantLock();→ 成员变量this.lock仍为null,后续lock.lock()抛NullPointerException; - volatile 字段(如
private volatile boolean shutdown)虽保证可见性,但若其 setter 方法未声明为public,外部无法触发优雅关闭。
测试环境掩盖问题,生产环境才暴露缺陷
单元测试常与被测类同包,所有包级方法都能调用,测试全部通过;但真实部署时:
- 限流组件被网关模块(不同 package)引用,
tryAcquire()调用失败; - 监控埋点通过反射读取
getQueueSize(),因方法非 public 而抛IllegalAccessException; - 故障注入平台尝试调用
forceFailOpen()控制开关,却因权限不足静默忽略。
这类问题不会在 CI 阶段暴露,上线后表现为“偶发超限”“监控数据缺失”“降级不生效”,排查成本极高。











