我试图弄清楚如何在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()
懒洋洋地创建,他们会从值的所有继承set
的main
方法(和线程)。
如果您在原始线程中设置值之前以某种方式使用了commonPool
(或parallel
调用了终端操作的任何池),情况就不会如此InhertiableThreadLocal
。
它们之间有什么相同和不同之处,看起来Java并行流中有RXJava中可用的一些元素,是吗?
考虑到我有2个CPU核心的事实,并行版本不是应该更快吗?有人能给我一个提示为什么并行版本比较慢吗?
在Java8中运行以下流示例: 产量: 当然,这并不奇怪。由于http://docs.oracle.com/javase/8/docs/api/index.html?overview-summary.html,流是顺序执行还是并行执行并不重要: 顺便说一下:使用(首选的)而不是生成相同的结果,用于顺序和并行执行。 JVM详细信息:
问题内容: 在Java8中运行以下流示例: 产量: 当然-这并不奇怪。由于http://docs.oracle.com/javase/8/docs/api/index.html?overview- summary.html ,流是顺序执行还是并行执行都没有关系: 除了标识为明确不确定的操作(例如findAny())之外,流是顺序执行还是并行执行都不应该更改计算结果。 AFAIK 是确定性的并且是关
是否可以为Java8并行流指定自定义线程池?我到处都找不到它。 如果我不能为不同的模块使用不同的线程池,这就意味着我不能在大多数真实世界的情况下安全地使用并行流。 请尝试以下示例。有些CPU密集型任务在单独的线程中执行。这些任务利用并行流。第一个任务被打破,因此每一步需要1秒(通过线程Hibernate模拟)。问题是其他线程会被卡住,等待中断的任务完成。这是一个虚构的示例,但假设一个servlet