当前位置: 首页 > 知识库问答 >
问题:

ExecutorService线程未继承的InheritableThreadLocal值

别旻
2023-03-14
import java.util.concurrent.Executors
import scala.concurrent.{ExecutionContext, Future}

object TestInheritableThreadLocal {

  def main(args: Array[String]): Unit = {

    implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(2))

    val tl: InheritableThreadLocal[String] = new InheritableThreadLocal[String]()
    tl.set("InitialValue")

    Future {
      println("111 " + Thread.currentThread() + tl.get())
      Future {
        println("222 " + Thread.currentThread() + tl.get())
      }
    }
    Thread.sleep(3000)

    Future {
      tl.set("NewInitialValue")
      println("333 " + Thread.currentThread() + tl.get())
      Future {
        println("444 " + Thread.currentThread() + tl.get())
      }
      Thread.sleep(3000)
    }
  }
}
111 Thread[pool-1-thread-1,5,main]InitialValue
222 Thread[pool-1-thread-2,5,main]InitialValue
333 Thread[pool-1-thread-1,5,main]NewInitialValue
444 Thread[pool-1-thread-2,5,main]InitialValue

是什么导致了这个问题,如何解决?

共有1个答案

戚令秋
2023-03-14

当您无法控制线程的创建时,不应该依赖InheritableThreadLocal。javadoc声明:

[...]当创建子线程时,子线程接收父线程具有值的所有可继承线程局部变量的初始值。

在您的示例中,线程是由executors.NewFixedThreadPool(2)返回的executorService创建的

然后提交第三个任务333,覆盖InheritableThreadLocal的值并打印它。当您提交第四个任务444时,ExecutorService使用现有线程来执行它。该线程已经有一个值,是以前继承的。

如何解决

在不知道自己想做什么的情况下,很难回答这个问题。但是,如果您想有效地使用InheritableThreadLocal,这一切都归结为了解和控制线程的创建,以及继承链。

 类似资料:
  • 问题内容: 输出量 自333线程产生于444线程以来,我一直期待输出的最后一行出现“ NewInitialValue”,而tl是本地可继承线程。 是什么导致此问题,如何解决? 问题答案: 当您无法控制线程的创建时,您不应依赖。Javadoc指出: […]创建子线程时,子级将接收父级具有值的所有可继承线程局部变量的初始值。 在您的示例中,线程是由返回者创建的 那是一个执行程序,最多将使用两个线程来执

  • 我正在尝试执行以下代码: 上述类由测试类继承: 以下是testng.xml文件: 我正在通过运行testng.xml文件并行执行上述测试方法。根据我的理解,可继承线程局部变量的值可以被子线程访问。但是当我执行上述测试类时,我观察到在测试方法中,可继承线程局部变量的值为。根据我的理解,“BeforeMethod”和“test方法”是BeforeClass方法的子线程。 以下是输出: 那么,为什么可继

  • 本文向大家介绍java多线程编程之InheritableThreadLocal,包括了java多线程编程之InheritableThreadLocal的使用技巧和注意事项,需要的朋友参考一下 InheritableThreadLocal的作用: 当我们需要在子线程中使用父线程中的值得时候我们就可以像使用ThreadLocal那样来使用InheritableThreadLocal了。 首先我们来看一

  • 假设我有一个Executors静态工厂方法的ExecutorService实例。 如果我从某个线程提交了一个调用,其中RetVal不是线程安全的本地实例化对象,那么当我从同一个线程获得()它时,我需要担心retvals的完整性吗?人们说局部变量是线程安全的,但我不确定当您返回一个本地实例化的对象并从其他线程接收它时,它是否适用。 下面是我的定制实现,我只是为了测试。您可以忽略EType枚举。

  • 问题内容: 假设我有一个利用该框架的应用程序 当我在调试器中运行此应用程序时,将使用以下(默认)名称创建一个线程:。如你所见,这并不是非常有用,而且据我所知,该框架没有提供一种简便的方法来命名已创建的线程或线程池。 那么,如何为线程/线程池提供名称呢?例如,。 问题答案: 你可以提供一个到。工厂将负责创建线程,并将能够为其命名。 引用Javadoc: 创建新线程 使用创建新线程。如果没有另外指定,

  • 我从主线程调用了下面的代码,使用ExecutorService池并启动一个线程来处理找到的每个文件。我正在尝试了解当主线程被kill命令终止时ExecutorService的行为。生成的线程会发生什么?一旦完成工作,它们会立即被杀还是终止? 还有没有更好/更安全的方法来编写下面的代码段,特别是如果我在无限循环中运行这部分,例如等待文件被放到输入目录并分配线程来处理它们?在这种情况下,我应该创建一个