gpt4 book ai didi

Java 8 并行流和 ThreadLocal

转载 作者:搜寻专家 更新时间:2023-10-30 21:29:10 25 4
gpt4 key购买 nike

我想弄清楚如何在 Java 8 并行流中复制 ThreadLocal 值。

所以如果我们考虑这个:

    public class ThreadLocalTest {

public static void main(String[] args) {
ThreadContext.set("MAIN");
System.out.printf("Main Thread: %s\n", ThreadContext.get());

IntStream.range(0,8).boxed().parallel().forEach(n -> {
System.out.printf("Parallel Consumer - %d: %s\n", n, ThreadContext.get());
});
}

private static class ThreadContext {
private static ThreadLocal<String> val = ThreadLocal.withInitial(() -> "empty");

public ThreadContext() {
}

public static String get() {
return val.get();
}

public static void set(String x) {
ThreadContext.val.set(x);
}
}
}

哪些输出

Main Thread: MAIN
Parallel Consumer - 5: MAIN
Parallel Consumer - 4: MAIN
Parallel Consumer - 7: empty
Parallel Consumer - 3: empty
Parallel Consumer - 1: empty
Parallel Consumer - 6: empty
Parallel Consumer - 2: empty
Parallel Consumer - 0: MAIN

有没有办法将 ThreadLocal 从 main() 方法克隆到为每次并行执行生成的线程中?

这样我的结果是:

Main Thread: MAIN
Parallel Consumer - 5: MAIN
Parallel Consumer - 4: MAIN
Parallel Consumer - 7: MAIN
Parallel Consumer - 3: MAIN
Parallel Consumer - 1: MAIN
Parallel Consumer - 6: MAIN
Parallel Consumer - 2: MAIN
Parallel Consumer - 0: MAIN

而不是第一个?

最佳答案

As Louis has stated in the comments ,您的示例可以很好地简化为捕获 lambda 表达式中局部变量的值

public static void main(String[] args)  {
String value = "MAIN";
System.out.printf("Main Thread: %s\n", value);

IntStream.range(0,8).boxed().parallel().forEach(n -> {
System.out.printf("Parallel Consumer - %d: %s\n", n, value);
});
}

从您的示例中看不出完整的用例是什么。

如果您确切知道哪些线程将从您的主线程启动,您可以考虑使用 InheritableThreadLocal

This class extends ThreadLocal to provide inheritance of values fromparent thread to child thread: when a child thread is created, thechild receives initial values for all inheritable thread-localvariables for which the parent has values.

在你的例子中,将 val 声明为 InheritableThreadLocal,因为 Thread 实例是为 parallel() 创建的ForkJoinPool#commonPool() 是延迟创建的,它们都继承自 main 方法(和线程)中的值 set

如果您在设置 InhertiableThreadLocal 之前以某种方式使用 commonPool(或调用 parallel 终端操作的任何池),情况就不会如此 原始线程中的值。

关于Java 8 并行流和 ThreadLocal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33926777/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com