Java 8个并行流和ThreadLocal
Java 8 parallel stream and 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
有没有办法让我从 main() 方法中将 ThreadLocal 克隆到为每次并行执行生成的线程中?
这样我的结果是:
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
而不是第一个?
,您的示例可以很好地简化为捕获 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 from
parent thread to child thread: when a child thread is created, the
child receives initial values for all inheritable thread-local
variables for which the parent has values.
在您的情况下,将 val
声明为 InheritableThreadLocal
,因为 ForkJoinPool#commonPool()
中为 parallel()
创建的 Thread
实例是延迟创建的,它们都将从 main
方法(和线程)中的值 set
继承。
如果您在设置原始线程。
我想知道如何在 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
有没有办法让我从 main() 方法中将 ThreadLocal 克隆到为每次并行执行生成的线程中?
这样我的结果是:
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
而不是第一个?
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 from parent thread to child thread: when a child thread is created, the child receives initial values for all inheritable thread-local variables for which the parent has values.
在您的情况下,将 val
声明为 InheritableThreadLocal
,因为 ForkJoinPool#commonPool()
中为 parallel()
创建的 Thread
实例是延迟创建的,它们都将从 main
方法(和线程)中的值 set
继承。
如果您在设置原始线程。