Comments (2)
- 你说的普通线程传递时(即
new Thread
),触发的是InheritableThreadLocal.childValue()
方法。 - 不同的初始化方法,如
initialValue()
、childValue()
、copy()
,其触发有确定的时机。
(展开说明见文后的引用内容)
具体你的需求,对应的用法 是
重写(override
)InheritableThreadLocal.childValue()
以代理到copy()
方法: @songxiaosheng
protected TtlObject childValue(TtlObject parentValue) {
return copy(parentValue);
}
PS:
Agent
使用方式 与copy
方法 是独立正交的。
Agent
方式只是在使用上的便利,省去API
方式要写的代码行(如调用TtlRunnable.get()
、TtlExecutors.getTtlExecutorService()
)。
更多这方面的使用与设计及其原因的说明 在已有的 issue 中有展开讨论: @songxiaosheng
摘一些内容如下:
关于初始化方法
相关的初始化方法还有
ThreadLocal#initialValue()
。这3个初始化方法 的区别是 做初始化操作的 生命周期时间点/触发时间 不同:
ThreadLocal#initialValue()
ThreadLocal
没有值时,取值(ThreadLocal#get()
方法)触发初始化。- 下面是一些注意点:
ThreadLocal#initialValue()
是 Lazy的;
即创建ThreadLocal
实例时,并不会触发ThreadLocal#initialValue()
调用。- 先设置值(
ThreadLocal#set(T)
)再取值,则不会触发调用ThreadLocal#initialValue()
;因为已经有值了。
即使设置的是null
,也不会触发。- 调用
ThreadLocal#remove()
再取值,会触发调用ThreadLocal#initialValue()
;因为没有值了。InheritableThreadLocal#childValue(T)
- 创建新线程时,用于初始化子线程的
InheritableThreadLocal
值。TransmittableThreadLocal#copy(T)
- 传递时,用于初始化 在任务(如
TtlRunnable
)执行中的TransmittableThreadLocal
值。不同初始化方法是独立正交的
这里可能值得强调一下这3个初始化方法的容易被忽视的地方:3个方法是独立正交的。
(好的系统设计应该这样,不同功能独立正交;系统大的功能 是通过 方便地组合/使用更小的功能 来实现。)展开一些的说明如下:
- 因为生命周期时间点/触发时间 不同,各自独立发挥作用。
- 子类包含进来的父类初始化方法,功能不变。
InheritableThreadLocal
是ThreadLocal
的子类,包含的ThreadLocal#initialValue()
功能不变。TransmittableThreadLocal
是InheritableThreadLocal
的子类,包含的ThreadLocal#initialValue()
、InheritableThreadLocal#childValue(T)
功能不变。系统设计最佳实践:结合业务扩展重写初始化方法,而不是用无业务含义的缺省实现
在
ThreadLocal
的使用中,看到初始化方法的扩展重写没有得到应有的重视与理解使用。即初始化方法没有重写,结果是在用无业务含义的缺省实现:
ThreadLocal#initialValue()
:返回null
InheritableThreadLocal#childValue(T)
:直接返回入参TransmittableThreadLocal#copy(T)
:直接返回入参这样的做法,导致 上面提到的『通过
ThreadLocal#set(T)
方法来完成初始化工作』。结果会导致:
- 需要用户主动调用
ThreadLocal#set(T)
来,用户使用麻烦/困难。- 通过用户调用
ThreadLocal#set(T)
来做初始化操作,因为语义不对应(即系统设计错误),
这样的实现方式往往会引发隐晦偶现的业务逻辑Bug!写一个示意Demo可以这样;但作为实际系统实现,
强烈推荐:结合业务与不同初始化方法的生命周期时间点 扩展重写好 相应的初始化方法。
用于重写初始化方法的
TransmittableThreadLocal
便利工具方法
TransmittableThreadLocal
提供了下面3个静态工具方法withInitial*
,可以方便地重写这些初始化方法的实现逻辑:
(如果没有静态工具方法withInitial*
,就要写一个TransmittableThreadLocal
子类来重写初始化方法,相对不方便)
from transmittable-thread-local.
感谢回复
from transmittable-thread-local.
Related Issues (20)
- withInitialAndCopier method is incompatible with versions before jdk1.8 HOT 1
- skywalking集成ttl 采集多线程数据无效 HOT 1
- 复现TransmittableThreadLocal数据在「不用TtlExecutors包裹的线程池」中概率丢失。 HOT 1
- TTL是否适用于tomcat的StandardThreadExecutor,尝试了agent的方式和显式包装的方式都不行 HOT 1
- 线程池每次执行完成后默认将上下文还原至调用线程的上下文原状,可以执行完成后将线程中的上下文全部清除掉吗 HOT 1
- 集成`Spring Reactor` HOT 1
- jdk11 报错。 HOT 4
- ttl是否不支持rocketMQ的上下文传递 HOT 1
- 在CompletableFuture中使用TTL,主线程执行完成,但CompletableFuture未完成,是否可以可以释放上下文,主线程释放上下文后,CompletableFuture是否还能拿到TTL的值 HOT 1
- 加入agent后报TtlTransformer: Fail to transform class xxx 错误 HOT 4
- agent方式使用TTL,jdk从8升到11之后项目启动报错 类重复加载: java.lang.LinkageError: loader java.net.URLClassLoader attempted duplicate class HOT 3
- “业务项目”在通过bytebuddy增强后,TTL+CompletableFuture无法再正常地进行上下文传递。 HOT 1
- 关于不修饰runnable使用TTL导致子线程泄露问题 HOT 3
- -
- 与其他探针放在一起使用的时候,如果ttlagent顺序在其他探针之后,探针失效无法跨线程 HOT 7
- 关于registerThreadLocal方法加锁和copy on write疑问 HOT 1
- 有必要关闭Inheritable能力么 HOT 5
- TTL使用完成后需要remove掉当前线程的值吗?如果不删除会不会引发OOM? HOT 3
- 主线程执行完后会remove,但是子线程执行完成后会restore恢复本地变量,子线程中的值变量如何清除? HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from transmittable-thread-local.