alibaba / transmittable-thread-local

📌 a missing Java std lib(simple & 0-dependency) for framework/middleware, provide an enhanced InheritableThreadLocal that transmits values between threads even using thread pooling components.
https://github.com/alibaba/transmittable-thread-local
Apache License 2.0
7.66k stars 1.69k forks source link

v2.12.1 NPE:在父子线程情况下`TransmittableThreadLocal<Map<String, String>>`新增map中的key值时 #333

Closed chen-shu-hao closed 2 years ago

chen-shu-hao commented 2 years ago

在父子线程情况下TransmittableThreadLocal<Map<String, String>> holder新增map中的key值时,会导致原有key对应的value值一定概率丢失为null,出现空指针NPE

oldratlee commented 2 years ago

https://github.com/alibaba/transmittable-thread-local/blob/a588b590232ddd04033d316bc25791afea772392/src/main/java/com/alibaba/ttl/TransmittableThreadLocal.java#L199-L216


下面假设你说的holder不是指 TransmittableThreadLocal.holder,而是你自己业务里的context

一般和使用方式相关,主要要注意的可能是

这些方面的问题 理解清楚了,应该是可以构造确定性复现的demo的。 这样并发相关的问题基本上独立于 TTL,只要有并发就要注意并解决好。


下面假设你说的holder就是指 TransmittableThreadLocal.holder

新增map中的key值 会导致原有key对应的value值一定概率丢失为null,出现空指针

TransmittableThreadLocal.holder 这个map 设计实现成: value 只能是 null。

PS: TransmittableThreadLocal.holderTTL的最核心数据,因为有大量的生产环境的使用,有问题的可能性不大。需要了解结合你的使用方式,有更完整的信息,以排查。


无论哪种情况,@chen-shu-hao 给一下 问题的信息:如NPE的栈、你的使用方式、环境 等等

期望能从你这边出这个问题的业务代码中, 请分离整理 一个可以(尽量有较大概率)复现问题的极简可运行Demo工程:❤️

否则:

chen-shu-hao commented 2 years ago

现在我解决了这个问题: 重新定义了一个新的TransmittableThreadLocal,没有使用主线程的TransmittableThreadLocal

oldratlee commented 2 years ago

@chen-shu-hao 解决了问题就好。❤️

这个 Issue 先 Close 了。如果还有问题可以继续讨论。

liuyq913 commented 2 years ago
private static TransmittableThreadLocal<Map<String, String>> transmittableThreadLocal = new TransmittableThreadLocal();

子线程修改了transmittableThreadLocal里面某个值, 会透传到主线程里面

oldratlee commented 2 years ago

private static TransmittableThreadLocal<Map<String, String>> transmittableThreadLocal = new TransmittableThreadLocal(); 子线程修改了transmittableThreadLocal里面某个值, 会透传到主线程里面

是的。缺省传递的是引用。

如果业务有修改并且没恰当的同步,业务这样的通信方式是不线程安全的使用方式,即有 bug。已有不少 issue 讨论过,可以找了看一下。

通过重写TransmittableThreadLocal#copy方法,可以定制传递方式。 参见项目的用户文档。 @liuyq913