# EnhancedInheritableThreadLocal **Repository Path**: thjyneg/EnhancedInheritableThreadLocal ## Basic Information - **Project Name**: EnhancedInheritableThreadLocal - **Description**: InheritableThreadLocal增强版本,支持主线程向线程池中已存在的线程注入threadLocal信息。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-06-02 - **Last Updated**: 2022-07-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # com.zwcoder.enhancedthreadlocal.EnhancedInheritableThreadLocal #### 介绍 ThreadLocal作为java原生提供的线程级变量池应用十分广泛,例如为了不破坏业务代码,环境变量,TraceID,操作日志信息的传递往往都会采用该技术。其中InheritableThreadLocal作为ThreadLocal的扩展,提供了跨线程的变量池传递,即父线程的线程变量池可以自动的传递到子线程的线程变量池,但其存在一个缺陷:不支持线程池。原因是InheritableThreadLocal的父子线程变量池的传递是发生在线程创建的构造函数中的。 然而,大部分企业代码中,往往都会禁止直接创建线程,而是通过线程池来运行线程任务。在这种场景下,线程在执行完任务后会一直保留,当下一个任务提交过来的时候直接使用,也就是说,线程的构造函数无法被确切的执行,InheritableThreadLocal的初始化当然也无法触发。因此,该机制失效,导致了需要通过transfer类去显示的传递以上信息。 Transfer类又遇到了一个问题,ThreadLocal的使用方式决定了其必须显示的调用代码,因此所有传递的信息都必须显示的写入Transfer类中,扩展难,且容易遗漏。 #### 软件架构 #####原理: 1.ThreadLocal的set和get方法中永远会获取当前线程的内容。 2.构造Runnable和Callable任务时,其线程仍然是主线程。 3.执行Runnable和Callable任务时,其线程为子线程。 #####思路说明: 扩展ThreadLocal的set方法,将所有ThreadLocal放入线程缓存----多级线程缓存。 在Runnable和Callable创建时,将缓存的线程缓存传入Runnable进行backup。get方法获取的内容为主线程内容。 在Runnable和Callable运行时,通过backup的线程缓存进行replay---set方法操作的是子线程。 #### 使用说明 1.用提供的EnhancedRunnable和EnhancedCallable对原有Runnable和Callable任务进行包装即可,无需改造线程池。 2.使用EnhancedThreadPoolTaskExecutor线程池即可,无需对Runnable和Callable进行包装。 ####注意 当前仅支持主线程调用线程池,不支持线程池的嵌套调用 #### 参与贡献 1. Fork 本仓库 3. 提交代码 4. 新建 Pull Request