Java 如何并行化创建复杂对象的步骤?

Java 如何并行化创建复杂对象的步骤?,java,concurrency,parallel-processing,Java,Concurrency,Parallel Processing,每个步骤彼此独立,每个步骤都将参数写入对象作为最终结果。 这些方法与它们的逻辑完全不同,没有递归 如果可能的话,我如何并行化这些步骤?开始,然后等待结果再分配 class MyItem { private param1, param2, param3; } MyItem item = new MyItem(); computeParam1(item); computeParam2(item); computeParam3(item); waitForAllParamsToBeSet(

每个步骤彼此独立,每个步骤都将参数写入对象作为最终结果。 这些方法与它们的逻辑完全不同,没有递归

如果可能的话,我如何并行化这些步骤?

开始,然后等待结果再分配

class MyItem {
    private param1, param2, param3;
}

MyItem item = new MyItem();

computeParam1(item);
computeParam2(item);
computeParam3(item);
waitForAllParamsToBeSet();
Future item1=ComputeParam1();
Future item2=ComputeParam2();
Future item2=ComputeParam3();
MyItem=新的MyItem();
assignParam1(item1.get());
assignParam2(item2.get());
assignParam3(item3.get());
由于所有
computeParamX()
接受一个
MyItem
参数并具有无效返回,因此它们具有的签名为。因此,您可以在并行流的
.forEach()
中调用它们来并行化它们的执行,如下所示:

Future<Type1> item1 = ComputeParam1();
Future<Type2> item2 = ComputeParam2();
Future<Type3> item2 = ComputeParam3();

MyItem item = new MyItem();

assignParam1(item1.get());
assignParam2(item2.get());
assignParam3(item3.get());
final MyItem item=new MyItem();
of(this::computeParam1,this::computeParam2,this::computeParam3)
.parallel()
.forEach(c->c.接受(项目));

由于
.forEach()
是终端操作,它将一直阻塞,直到所有操作完成,因此在它返回后,您可以安全地使用
对象。

在Java 8中,您只需创建任务集合,如下所示:

final MyItem item = new MyItem();
Stream.<Consumer<MyItem>>of(this::computeParam1, this::computeParam2, this::computeParam3)
          .parallel()
          .forEach(c -> c.accept(item));

这是一个很好的特性,在使用spring时更是如此:请注意,使用这种方法(仅使用变通方法)不可能指定线程池:这种方法依赖于ForkJoinPool,它启动的线程数量与目标计算机上与Runtime.getRuntime()对应的内核数量相同。availableProcessors()但是,由于系统属性,例如java.util.concurrent.ForkJoinPool.common.parallelism,您仍然可以修改默认值。这里有更多详细信息是的,但该线程是关于在默认ForkJoinPool中执行的每个使用并行流的任务,如果其他任务正在减慢甚至使该池死锁,这可能是一个问题。没错:强大的力量带来巨大的责任:-)因此,现在您正在从多个线程向
写入。我们对
MyItem
类了解不够,所以不知道这是安全的。@weston是的,你说得对。在使用此方法之前,必须确保
computeParamX
方法不会干扰。OP说它们是独立的,我看不出有什么理由不相信。怀疑的首要原因是,如果计算是独立的,那么为什么要向它们传递一个实例,而不是在计算之后才分配?i、 在这个问题中,为什么不是:
item.setParam1(computeParam1())等等?@weston是的,是的,是的,你有更正确的设计。我也喜欢。如果OP接受你而不是我的答案,我不会生气。我的意图是展示如何将任意方法表示为lambda,以便使用流API处理它们。
Collection<Runnable> tasks = Arrays.asList(
    () -> System.out.println("Compute param1"),
    () -> System.out.println("Compute param2"),
    () -> System.out.println("Compute param3")
);
tasks.parallelStream().forEach(Runnable::run);