Java 8启用带布尔值的parallel()流?
我想知道如何设计可以并发运行或单线程运行的方法。例如,我有这样一个方法:Java 8启用带布尔值的parallel()流?,java,multithreading,parallel-processing,java-8,java-stream,Java,Multithreading,Parallel Processing,Java 8,Java Stream,我想知道如何设计可以并发运行或单线程运行的方法。例如,我有这样一个方法: /** * Produces the norm of the two vector {@code v1}. * * @param v1 * The first vector. * * @param v2 * The second vector * * @throws MathException * Of type {@code D
/**
* Produces the norm of the two vector {@code v1}.
*
* @param v1
* The first vector.
*
* @param v2
* The second vector
*
* @throws MathException
* Of type {@code DIMENSION_MISMATCH} if
* {@code v1.getDimension()} is != {@code v2.getDimension()}.
*/
public static Function<Vector, Double> norm = (v) -> {
return Math.sqrt(
IntStream.range(0, v.getDimension()).mapToDouble(i -> Math.pow(v.getEntry(i), 2)).sum());
};
/**
*生成两个向量{@code v1}的范数。
*
*@param v1
*第一个向量。
*
*@param v2
*第二个向量
*
*@抛出异常
*类型为{@code-DIMENSION_-MISMATCH}if
*{@code v1.getDimension()}是!={@code v2.getDimension()}。
*/
公共静态函数范数=(v)->{
return Math.sqrt(
IntStream.range(0,v.getDimension()).mapToDouble(i->Math.pow(v.getEntry(i),2)).sum();
};
如果我想使嵌入式流并行,那么我可以再次创建相同的方法,并将parallel()
添加到流中,但这会增加很多样板文件。是否有可以使用的并行(布尔)
开关?创建两个函数
一个命名为norm(如所述的实现),另一个命名为parallelNorm。您可以在这些函数之间重用代码
让编码类控制并行性
您的函数规范驻留在某个类中。我会的
- 使函数范数非静态
- 在encosing类中引入了名为parallel的最终布尔成员变量
- 初始化构造函数中的并行成员变量
- 函数norm将根据并行成员变量的值使用并行或非并行流
然后我将使类ParallelNorm扩展Norm,该类将使用并行实现@Override Norm函数在API本身中没有类似的开关,但您可以非常轻松地添加它:
public static Function<Vector, Double> getNorm(boolean parallel) {
return v -> {
IntStream stream = IntStream.range(0, v.getDimension());
stream = parallel ? stream.parallel() : stream;
return Math.sqrt(stream.mapToDouble(i -> Math.pow(v.getEntry(i), 2)).sum());
};
};
公共静态函数getNorm(布尔并行){
返回v->{
IntStream=IntStream.range(0,v.getDimension());
stream=parallel?stream.parallel():stream;
返回Math.sqrt(stream.mapToDouble(i->Math.pow(v.getEntry(i),2)).sum();
};
};
这段代码只是调用或不调用布尔参数。只是想发布一个示例,说明我认为API的总体外观,以了解您的想法(我希望Apache Commons Math将在4.0中采用这一点,但同时该模块将在此处提供):
/**
*返回一个{@link BiFunction}乘以第一个向量{@code v1}
*乘以第二个向量{@code v2}。
*
*示例{@code multiply().apply(v1,v2);}
*
*@抛出异常
*类型为{@code-DIMENSION_-MISMATCH}if
*{@code v1.getDimension()}是!={@code v2.getDimension()}。
*/
公共静态双函数乘法(){
返回向量函数。乘法(false);
};
/**
*返回一个{@link BiFunction}乘以第一个向量{@code v1}
*乘以第二个向量{@code v2}。
*
*示例{@code multiply(true).apply(v1,v2);}
*
*@param并行
*是否并行执行乘法。
*
*@抛出异常
*类型为{@code-DIMENSION_-MISMATCH}if
*{@code v1.getDimension()}是!={@code v2.getDimension()}。
*/
公共静态双函数乘法(布尔并行){
返回(v1,v2)->{
检查尺寸不匹配(v1,v2);
IntStream=range(0,v1.getDimension());
stream=parallel?stream.parallel():stream;
返回新向量(stream.mapToDouble(i->v1.getEntry(i)
*v2.getEntry(i)).toArray();
};
}
想法
Ole这仍然需要讨论和建议,而“最佳”一词只是强调指出,去掉它并不会改变这个基本问题,因为这个问题仍然是基于观点的,同时又过于宽泛。去掉“最好”这个词只是混淆了这些问题。@JarrodRoberson出于好奇,你能想到多少种不同的实现方式?当然,在编程中,解决问题的方法往往不同。这不一定会使问题的观点过于广泛……@JarrodRoberson不一定。当有两个相同的解决方案只是写得不同时,意见就会起作用。如果不是,就有一种无偏见的方法来比较它们,比如性能。你会诚实地在这里写一个Spring解决方案吗?因为你可以为每个可能的问题写一个Spring解决方案。不,对于您是否想要它没有任何意见:OP想要它。(如果您考虑性能方面的
parallel()
,您可能会发现unordered()
也可以提高性能。)BiFunction
也可以在其中使用(尽管它使用了包装器类型,但很好…).我不认为条件运算符会增加可读性。普通的if(parallel)stream=stream.parallel()代码>直接完成工作。我同意@Holger的观点,但仍然是非常简洁和漂亮的解决方案!谢谢你们!真是太好了!我正在考虑为矩阵/向量模块添加并行特性,以便试验算法中的并发性。你认为在函数级嵌入它有意义吗?或者我应该针对更大的代码块吗?谢谢-我也喜欢你的想法。我想我可能会执行norm(),它只返回非并行版本和norm(布尔值),norm可以选择打开并行版本。
/**
* Returns a {@link BiFunction} that multiplies the first vector {@code v1}
* times the second vector {@code v2} .
*
* Example {@code multiply().apply(v1, v2);}
*
* @throws MathException
* Of type {@code DIMENSION_MISMATCH} if
* {@code v1.getDimension()} is != {@code v2.getDimension()}.
*/
public static BiFunction<Vector, Vector, Vector> multiply() {
return VectorFunctions.multiply(false);
};
/**
* Returns a {@link BiFunction} that multiplies the first vector {@code v1}
* times the second vector {@code v2} .
*
* Example {@code multiply(true).apply(v1, v2);}
*
* @param parallel
* Whether to perform the multiplication in parallel.
*
* @throws MathException
* Of type {@code DIMENSION_MISMATCH} if
* {@code v1.getDimension()} is != {@code v2.getDimension()}.
*/
public static BiFunction<Vector, Vector, Vector> multiply(boolean parallel) {
return (v1, v2) -> {
checkDimensionMismatch(v1, v2);
IntStream stream = range(0, v1.getDimension());
stream = parallel ? stream.parallel() : stream;
return new Vector(stream.mapToDouble(i -> v1.getEntry(i)
* v2.getEntry(i)).toArray());
};
}