即使使用 Vert.x 和 Log4j2 将"isThreadContextMapInheritable"设置为 true,也无法获取 ThreadContext 值



我使用的是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中的所有内容。

VertxParallel Stream都使用Fork-Join公共池。只有在初始化公共池之前设置的线程上下文值在子线程中可用。


即使没有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

最新更新