【问题标题】:Can a child thread modify its parent's Threadlocal variable?子线程可以修改其父线程的 Threadlocal 变量吗?
【发布时间】:2015-04-24 22:33:25
【问题描述】:

我有 2 个线程,每个线程都有一个名为 threadLocal 的 Threadlocal 列表,它们都将生成子线程。我希望子线程能够修改父线程的本地线程。

我尝试将父级本身传递给子级,以便它可以调用 parent.threadLocal.get().add(x) 但这会导致空指针异常。当父调用 threadLocal.get().add(x) 时,它能够将 x 添加到列表中就好了。

我知道问题出在 .add(x) 上,因为让孩子调用 .get() 不会导致异常。我还尝试将 threadLocal 本身传递给孩子,这给出了同样的错误。

有没有办法做到这一点?

【问题讨论】:

  • 如果你需要从多个线程访问变量线程本地化的目的是什么?
  • 另一种可能性是从子线程调用父方法,该方法将修改其自己的 ThreadLocal 列表。
  • @Eranda 之所以需要是 Threadlocal 是因为有多个父母需要有自己的列表
  • @FelipeMartinsMelo 父线程没有方法,对象有方法。如果子线程调用一个方法,它会在该子线程上运行,而不是在父线程上运行,因此它将获取子线程的 ThreadLocal,而不是父线程的

标签: java multithreading thread-local


【解决方案1】:

您可以检索父级中的列表并将其传递给子级,或使用InheritableThreadLocal

使用InheritableThreadLocal 表示将值复制到任何子线程。

请注意,在任何一种情况下,您都不能更改 父级 ThreadLocal 变量的值,但您可以改变该变量所引用的对象。在您的情况下,只要您正确处理并发,在列表中调用 .add(...) 就可以正常工作,例如通过使用CopyOnWriteArrayList

【讨论】:

  • 有没有办法让孩子修改其父母的变量?
  • @CrazyBurrito 不是直接的,但是很容易将变量包装在对象中并改变对象。例如。你可以有一个保存值的单元素数组,或者一个自定义的“持有人”对象。然后您只需更改数组或持有者中的值,更改对父项可见。确保在做类似的事情时处理并发问题。
  • 那么让我看看我是否理解你。所以我可以让父级创建一个 Threadlocal 数组,其中一个列表作为唯一元素。然后我将数组传递给孩子,它就能修改里面的列表?
  • @CrazyBurrito 如果你只是想修改一个列表,你不需要包装它。你可以做list.add(item) - 这不会改变变量,它会改变List 对象。父变量仍然指向同一个列表,但现在列表已经改变。没关系。你不能做的是将父级的 ThreadLocal 变量指向一个完全不同的列表。
  • 但是,正如我提到的,你必须小心并发问题,例如通过使用 CopyOnWriteArrayList - 在答案中值得一提,已编辑
猜你喜欢
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多