即使在使用 Vert.x 和 Log4j2 将“isThreadContextMapInheritable”设置为 true 后也没有获取 ThreadContext 值
Posted
技术标签:
【中文标题】即使在使用 Vert.x 和 Log4j2 将“isThreadContextMapInheritable”设置为 true 后也没有获取 ThreadContext 值【英文标题】:Not getting ThreadContext values even after setting "isThreadContextMapInheritable" to true, using Vert.x and Log4j2 【发布时间】:2021-03-12 02:36:23 【问题描述】:我正在使用 Vertx 和 Log4j2。
这是Remote.java
的代码
public class Remote extends AbstractVerticle
@Override
public void start() throws Exception
System.setProperty("isThreadContextMapInheritable", "true");
ThreadContext.put("1", "Company");
ThreadContext.put("2", "Sector");
ThreadContext.put("3", "Address");
ArrayList<String> arrayList = new ArrayList<>();
for (int i = 1; i < 4; i++)
arrayList.add(String.valueOf(i));
arrayList.parallelStream().forEach(s ->
System.out.println("Key " + s + " Value is " + ThreadContext.get(s) + " Name: " + Thread.currentThread().getName());
);
System.out.println("After parallelStream");
这是我的StartVerticle.java
代码
public class StartVerticle
public static void main(String[] args)
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(new Remote());
当我运行上面的代码时我的输出是
Key 2 Value is Sector Name: vert.x-eventloop-thread-0
Key 1 Value is null Name: ForkJoinPool.commonPool-worker-3
Key 3 Value is null Name: ForkJoinPool.commonPool-worker-5
After parallelStream
您能帮我获得以下输出吗?
Key 2 Value is Sector Name: vert.x-eventloop-thread-0
Key 1 Value is Company Name: ForkJoinPool.commonPool-worker-3
Key 3 Value is Address Name: ForkJoinPool.commonPool-worker-5
After parallelStream
我还打印了线程名称以供参考。
在不使用 Vertx 的情况下,将isThreadContextMapInheritable
设置为true
后,我能够打印ThreadContext
中的所有内容。
【问题讨论】:
【参考方案1】:Vertx
和 Parallel Stream
都使用 Fork Join Common Pool。只有在公共池初始化之前设置的线程上下文值在子线程中可用。
即使没有 Vertx,在第一个并行流之后设置的 ThreadContext
值在子线程中也将不可用。例如,
public static void main(String[] args) throws Exception
System.setProperty("isThreadContextMapInheritable", "true");
IntStream.range(0, 5)
.parallel()
.forEach(System.out::println);
ThreadContext.put("1", "Company");
ThreadContext.put("2", "Sector");
ThreadContext.put("3", "Address");
ArrayList<String> arrayList = new ArrayList<>();
for (int i = 1; i < 4; i++)
arrayList.add(String.valueOf(i));
arrayList.parallelStream()
.forEach(s ->
System.out.println("Key " + s + " Value is " + ThreadContext.get(s) + " Name: " + Thread.currentThread()
.getName());
);
这会打印出来
Key 1 Value is null Name: ForkJoinPool.commonPool-worker-5
Key 3 Value is null Name: ForkJoinPool.commonPool-worker-1
Key 2 Value is Sector Name: main
在我们的例子中,公共池在Vertx
启动时被初始化。此时,没有设置线程上下文值。
所以一种选择是在启动vertx之前在main()
中设置线程上下文。
public static void main(String[] args)
System.setProperty("isThreadContextMapInheritable", "true");
ThreadContext.put("1", "Company");
ThreadContext.put("2", "Sector");
ThreadContext.put("3", "Address");
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(new Remote());
产生输出,
Key 2 Value is Sector Name: vert.x-eventloop-thread-0
Key 3 Value is Address Name: ForkJoinPool.commonPool-worker-2
Key 1 Value is Company Name: ForkJoinPool.commonPool-worker-1
After parallelStream
【讨论】:
谢谢。但是我的应用程序在创建 vertx 实例后初始化值。有没有办法从 ThreadContext 中获取值,只是从我在代码中使用它的方式?以上是关于即使在使用 Vert.x 和 Log4j2 将“isThreadContextMapInheritable”设置为 true 后也没有获取 ThreadContext 值的主要内容,如果未能解决你的问题,请参考以下文章