【问题标题】:InheritableThreadLocal with parallel stream and AOP具有并行流和 AOP 的 InheritableThreadLocal
【发布时间】:2021-04-10 08:03:03
【问题描述】:

我正在使用 InheritableThreadLocal 为线程和子线程准备数据。

static InheritableThreadLocal<SomeType> instance

另外,我正在使用类似这样的并行流:

someStream.parallel().forEach(this::doSomething);

另外,我用的是spring AOP,会被doSomething方法触发:

@Around(value = "within(package.SomeService+)")
public Object execution(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
   instance.get(); // sometimes value is null sometimes not
}

InheritableThreadLocal 可以在除 AOP 执行方法之外的任何地方正常工作。有时实例不包含值。你知道为什么吗? 如果我将实例的值设置为并行流函数的第一行,这与并行流有关,我没有问题。你知道原因还是我错过了什么?

【问题讨论】:

  • 这 someStream.forEach(this::doSomething);有效吗?
  • 但是如果 doSomething 在不同的线程中被调用(这是在并行流上使用操作时的可能性),难道不应该期望 instance 将属于不同的线程?您如何确保在所有这些线程中初始化线程本地?
  • @dreamcrash 是的,someStream.forEach 有效,但我需要并行执行。
  • @ernest_k 如果我理解正确 InheritableThreadLocal 需要自动将此值添加到子线程中,我可以在除 AOP 方法之外的所有方法中的所有子线程中看到此值
  • @AkifHadziabdic 理论上是的,但我还是会尝试以防万一

标签: java spring spring-boot spring-aop


【解决方案1】:

从分享的关于这个问题的少量信息,我需要做一些猜测: someStream.parallel() 将使用默认的线程池,即 ForkJoinPool.commonPool()。这些线程被重用。使用 InheritableThreadLocal 时,只有在创建 ChildThread 时才会“继承”/共享父线程的值。以后当 ParentThread 的 Value 发生变化时,ChildThreads 的值不再变化。

所以我猜 AOP 也在使用 defaultThread 池,并且在您执行代码之前和设置 parentThread 的值之前生成 ChildThreads(应该继承给子线程,但不会,因为线程是重用而不是重新创建)。

使用 InheritableThreadLocal 和默认的 Threadpool 对我来说没有意义。您可能想研究使用这样的自定义线程池 https://www.baeldung.com/java-8-parallel-streams-custom-threadpool

【讨论】:

    猜你喜欢
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多