普通块实战是用基础语言特性在任意代码段嵌入轻量级局部记录能力,支持命名计时块、上下文快照、阈值触发、资源自动收尾及ThreadLocal上下文链,实现无侵入的耗时与状态追踪。

在执行耗时任务时,只关心整体耗时是不够的;真正影响优化决策的,往往是中间关键步骤的耗时分布和对应变量状态。所谓“普通块实战”,指不依赖AOP、不修改方法签名、不引入复杂框架,仅用基础语言特性,在任意代码段内嵌入轻量级局部记录能力。
用带命名的计时块包裹关键逻辑
避免手写 start/end 时间戳,改用可复用的结构化计时块。例如 Java 中封装一个静态工具方法:
- 接收一个 任务名称 和一个 执行体(Runnable/Callable)
- 自动记录进入时刻、执行完成时刻,并打印形如
[parse_json] elapsed 127 ms的日志 - 若需捕获中间变量,可在 Runnable 内部显式传入引用容器(如 AtomicReference、Map 或自定义 Holder)
在循环或分阶段处理中插入带上下文的快照点
比如批量解析文件时,每处理完 100 条就记录一次当前已处理条数、内存占用、最新一条数据 ID:
- 不依赖全局状态,而是把快照逻辑封装进
SnapshotPoint.log("after_100", () -> Map.of("count", i, "lastId", item.id)) - 快照内容自动附带时间戳和调用堆栈简写(如
Parser.java:42),便于回溯定位 - 支持设置阈值,仅当耗时超 200ms 或变量值异常(如 null、负数)时才落盘,减少干扰
结合 try-with-resources 实现自动收尾与变量归档
对需要严格生命周期管理的中间状态(如临时缓存、连接句柄、统计计数器),可用自定义资源类:
- 定义
TimingScope scope = new TimingScope("db_batch_write") - 在
try (scope)块内操作变量,scope.put("batchSize", 500)、scope.put("affectedRows", rows) - 离开 try 块时自动触发
close(),汇总耗时 + 所有 put 过的键值对,输出结构化日志或发往监控端点
用 ThreadLocal 存储当前任务的上下文快照链
适用于嵌套调用场景(如 Controller → Service → DAO),希望每个层级都能向同一份执行快照追加信息:
- 初始化时
TaskContext.start("order_create")创建线程本地链表 - 各子步骤调用
TaskContext.record("validate", Map.of("passed", true))或TaskContext.record("sql_exec", durationMs) - 最终统一 flush,生成类似
{"task":"order_create","steps":[{"name":"validate","data":{"passed":true}},{"name":"sql_exec","data":18.3}]}

















