java—使用vert.x和log4j2,即使将“isthreadcontextmapinheritable”设置为true,也无法获取threadcontext值

ijnw1ujt  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(573)

我使用的是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,我就可以打印文件中的所有内容 ThreadContext ,设置后 isThreadContextMapInheritabletrue .

ubof19bj

ubof19bj1#

Vertx 以及 Parallel 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 开始。此时,没有设置线程上下文值。
因此,一个选项是在中设置线程上下文 main() 在启动vertx之前。

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

相关问题