Java 8并行流和ThreadLocal

我试图弄清楚如何在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

而不是第一个?

回答:

正如Louis在评论中所述,您的示例可以简化为捕获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

此类扩展ThreadLocal为提供 :创建

时,子级将接收父级具有值的所有可继承线程局部变量的初始值。

在你的情况下,宣布val作为InheritableThreadLocal,因为Thread实例为创建parallel()ForkJoinPool#commonPool()懒洋洋地创建,他们会从值的所有继承setmain方法(和线程)。

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

以上是 Java 8并行流和ThreadLocal 的全部内容, 来源链接: utcz.com/qa/412443.html

回到顶部