Java 平行流-多少是平行的?
我有一个并行流,如下面我的Java 平行流-多少是平行的?,java,java-stream,Java,Java Stream,我有一个并行流,如下面我的Runner.java所示。但我意识到Runner类中的聚合方法是按顺序运行的。我想这是因为我有一个forEach,这个循环不能被打破,尽管我不确定。我对这种连续性的分析是基于我在下面的类的getter方法中打印的线程名称 虽然下面的代码有一个1000个对象的列表,但为了让较小的日志能够粘贴到这里,我将列表更改为10个项目以打印线程名称。日志位于Runner.java之后。查看它们,聚合方法总是由主线程执行,而不是由CommonPool执行。对于1000个项目也观察到了
Runner.java
所示。但我意识到Runner类中的聚合方法是按顺序运行的。我想这是因为我有一个forEach
,这个循环不能被打破,尽管我不确定。我对这种连续性的分析是基于我在下面的类的getter方法中打印的线程名称
虽然下面的代码有一个1000个对象的列表,但为了让较小的日志能够粘贴到这里,我将列表更改为10个项目以打印线程名称。日志位于Runner.java
之后。查看它们,聚合方法总是由主线程执行,而不是由CommonPool
执行。对于1000个项目也观察到了相同的行为。如果forEach是导致顺序执行的原因,有人能帮我吗
Employee.java
public class Employee {
private double salary;
private String fName;
private String lName;
public Employee(double salary, String fName, String lName) {
this.salary = salary;
this.fName = fName;
this.lName = lName;
}
public Employee() {
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String getfName() {
System.out.println("Thread.currentThread() + \"for getFname\" = " + Thread.currentThread() +
" for getFname");
return fName;
}
public void setfName(String fName) {
this.fName = fName;
}
public String getlName() {
return lName;
}
public void setlName(String lName) {
this.lName = lName;
}
@Override
public String toString() {
return "E{" +
"s=" + salary +
", N='" + fName + '\'' +
'}';
}
}
跑步者等级:
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Runner {
public static void main(String[] args) {
ArrayList<Employee> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
list.add(new Employee(i * 100, "A" + i, "Z" + i));
}
long l = System.currentTimeMillis();
List<Employee> collect = list
.parallelStream()
.collect(Collectors.collectingAndThen(Collectors.groupingBy(Employee::getfName), Runner::aggregate));
System.out.println("collect = " + collect.size());
System.out.println(collect.stream().mapToDouble(e -> e.getSalary()).sum());
}
private static List<Employee> aggregate(Map<String, List<Employee>> t) {
ArrayList<Employee> emps = new ArrayList<>();
t.entrySet()
.forEach(e -> {
System.out.println("Thread.currentThread() + \"within agrgate\" = " + Thread.currentThread() + "within agrgate");
Employee e1 = new Employee();
e.getValue().forEach(r -> {
e1.setSalary(e1.getSalary() + r.getSalary());
e1.setfName(r.getfName());
});
emps.add(e1);
});
return emps;
}
}
该方法来自接口iterable,其中“按迭代顺序执行操作…”
然后,您可以为每个应用程序使用流
t.entrySet().parallelStream().forEach( e->{
更好的方法是让
groupingBy
收集器首先计算总和,而不是将其收集到列表中,然后执行另一种形式的缩减。
t.entrySet().parallelStream().forEach( e->{