跨线程threadlocal
1 装饰器
core data
https://blog.csdn.net/avatar6780/article/details/135246200
public class ThreadLocalTransferDecorator {
public static Runnable decorate(Runnable runnable) {
return new ThreadLocalTransferRunnable(runnable);
}
private static class ThreadLocalTransferRunnable implements Runnable {
抢占线程新建的入口
旧线程创建线程并get threadlocal,传入新线程
2 skywalking
https://developer.aliyun.com/article/1121466
- 只拦截增强带有
@TraceCrossThread注解的类: - 通过装饰的方式包装任务,避免大刀阔斧的修改
| 原始类 | 提供的包装类 | 拦截方法 | 使用技巧 |
| Callable | CallableWrapper | call | CallableWrapper.of(xxxCallable) |
| Runnable | RunnableWrapper | run | RunnableWrapper.of(xxxRunable) |
| Supplier | SupplierWrapper | get | SupplierWrapper.of(xxxSupplier) |
SkyWalking Agent 会给被增强的类中扩展一个专用属性的机制是这样的:这个类会被修改,实现了接口EnhancedInstance,此接口中提供了2个方法来读写这个扩展属性
public interface EnhancedInstance {
Object getSkyWalkingDynamicField();
void setSkyWalkingDynamicField(Object value);
}
这个扩展属性就是一个普通的 Object ,在宿主应用这边感知不到它的存在,因为它不是在宿主应用中定义的;但是在 Agent 的上下文中可将其作为数据载体,在如下这些场景使用:
https://www.cnblogs.com/lwmp/p/18919483
1. 字节码增强(Bytecode Instrumentation)
SkyWalking Agent 通过 字节码增强技术(基于 ByteBuddy 或 ASM),在运行时修改类的字节码,自动注入 TraceID 传递逻辑:
- 拦截线程池创建:
当应用创建ThreadPoolExecutor、ScheduledExecutorService等线程池时,Agent 会动态插入代码,包装原始任务(如Runnable/Callable)。 - 拦截异步框架:
针对CompletableFuture、RxJava、Spring Async 等异步编程模型,Agent 会拦截其任务提交和执行过程。
2. 上下文传递(Context Propagation)
SkyWalking 使用 ThreadLocal 的扩展机制 ContextManager 存储 TraceID 和 Span 信息,并通过以下方式跨线程传递:
- 任务包装器模式:
在提交任务时,捕获当前线程的上下文(TraceID、Span 等),并封装到任务中。当任务在新线程中执行时,自动恢复上下文。 - 线程工厂增强:
对于自定义线程池,Agent 会增强其ThreadFactory,确保新创建的线程继承父线程的上下文。
浙公网安备 33010602011771号