[英]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
此類擴展
ThreadLocal
以提供從父線程到子線程的值繼承:當創建子線程時,子線程接收父線程具有值的所有可繼承線程局部變量的初始值。
在您的情況下,將val
聲明為InheritableThreadLocal
,因為在ForkJoinPool#commonPool()
中為parallel()
創建的Thread
實例是惰性創建的,它們都將從main
方法(和線程)中set
的值繼承。
如果您在原始線程中設置InhertiableThreadLocal
值之前以某種方式使用了commonPool
(或調用parallel
終端操作的任何池),則情況InhertiableThreadLocal
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.