Coder Social home page Coder Social logo

Comments (2)

oldratlee avatar oldratlee commented on June 27, 2024
  • 你说的普通线程传递时(即new Thread),触发的是InheritableThreadLocal.childValue()方法。
  • 不同的初始化方法,如initialValue()childValue()copy(),其触发有确定的时机。
    (展开说明见文后的引用内容)

具体你的需求,对应的用法 是
重写(overrideInheritableThreadLocal.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个初始化方法 的区别是 做初始化操作的 生命周期时间点/触发时间 不同:

  1. ThreadLocal#initialValue()
    • ThreadLocal没有值时,取值(ThreadLocal#get()方法)触发初始化。
    • 下面是一些注意点
    • ThreadLocal#initialValue()Lazy的;
      即创建ThreadLocal实例时,并不会触发ThreadLocal#initialValue()调用。
    • 先设置值(ThreadLocal#set(T))再取值,则不会触发调用ThreadLocal#initialValue();因为已经有值了。
      即使设置的是null,也不会触发。
    • 调用ThreadLocal#remove()再取值,会触发调用ThreadLocal#initialValue();因为没有值了。
  2. InheritableThreadLocal#childValue(T)
    • 创建新线程时,用于初始化子线程的InheritableThreadLocal值。
  3. TransmittableThreadLocal#copy(T)
    • 传递时,用于初始化 在任务(如TtlRunnable)执行中的TransmittableThreadLocal值。

不同初始化方法是独立正交的

这里可能值得强调一下这3个初始化方法的容易被忽视的地方:3个方法是独立正交的。
(好的系统设计应该这样,不同功能独立正交;系统大的功能 是通过 方便地组合/使用更小的功能 来实现。)

展开一些的说明如下:

  • 因为生命周期时间点/触发时间 不同,各自独立发挥作用。
  • 子类包含进来的父类初始化方法,功能不变。
    • InheritableThreadLocalThreadLocal的子类,包含的ThreadLocal#initialValue()功能不变。
    • TransmittableThreadLocalInheritableThreadLocal的子类,包含的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.

songxiaosheng avatar songxiaosheng commented on June 27, 2024

感谢回复🌺,我研究下

from transmittable-thread-local.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.