InheritableThreadLocal当您无法控制线程的创建时,您不应依赖。Javadoc指出:
[…]创建子线程时,子级将接收父级具有值的所有可继承线程局部变量的初始值。
在您的示例中,线程是由
ExecutorService返回者创建的
Executors.newFixedThreadPool(2)
那是一个执行程序,最多将使用两个线程来执行您的任务。从javadoc
创建一个线程池,该线程池重用在共享的无边界队列上操作的固定数量的线程。在任何时候,最多
nThreads线程都是活动的处理任务。如果在所有线程都处于活动状态时提交了其他任务,则它们将在队列中等待,直到某个线程可用为止。
这是一个实现细节,但是这些线程是根据需要延迟创建的。当您提交第一个任务时
111,对的调用
submit将创建并启动一个新线程。这个新线程将继承该值
InitialValue。同样,当该线程提交第二个任务时
222,其对的调用
submit将强制创建第二个线程,该第二个线程也将继承
InitialValue。
然后,您提交第三个任务,
333覆盖
InheritableThreadLocal的值并打印。当您提交第四个任务时
444,会
ExecutorService使用现有线程来执行它。该线程已经具有一个值,该值是先前继承的。
怎么解决
如果不知道自己想做什么,很难回答。但是,如果您想有效地使用
InheritableThreadLocal,那么一切都取决于了解和控制线程的创建,并因此控制继承链。
例如,您可以创建并使用
ExecutorService,为每个提交的任务创建并使用新线程。
同样,您可以使用另一种机制来传播该值:
AtomicReference不变值的lambda捕获。



