我使用ExecutorService和Future(这里是示例代码)在一个带有超时的单独线程中运行一个进程(线程"生成"发生在AOP方面).
现在,主线程是Resteasy请求.Resteasy使用一个或多个ThreadLocal变量来存储我需要在Rest方法调用中的某个时刻检索的一些上下文信息.问题是,由于Resteasy线程在新线程中运行,因此ThreadLocal变量将丢失.
将Resteasy使用的任何ThreadLocal变量"传播"到新线程的最佳方法是什么?似乎Resteasy使用多个ThreadLocal变量来跟踪上下文信息,我想"盲目地"将所有信息传递给新线程.
我查看了子类化ThreadPoolExecutor并使用beforeExecute方法将当前线程传递给池,但我找不到将ThreadLocal变量传递给池的方法.
有什么建议吗?
谢谢
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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
产量
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
Run Code Online (Sandbox Code Playgroud)
我期待输出的最后一行中的"NewInitialValue",因为333 Thread产生了Thread 444,而tl是一个可继承的本地线程.
是什么导致了这个问题,如何解决?
我有 2 个线程,每个线程都有一个名为 threadLocal 的 Threadlocal 列表,它们都将产生子线程。我希望子线程能够修改父线程的 threadLocal。
我尝试将父级本身传递给子级,以便它可以调用 parent.threadLocal.get().add(x) 但这会导致空指针异常。当父调用 threadLocal.get().add(x) 它能够将 x 添加到列表中就好了。
我知道问题出在 .add(x) 上,因为让孩子只调用 .get() 不会导致异常。我也尝试将 threadLocal 本身传递给孩子,这给出了同样的错误。
有没有办法做到这一点?