目录
一、主程序
package xyz.jangle.thread.test.nxi_13.streamvsforkjoin;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;
/**
* 11.13、使用流处理大数据(比较Stream和forkjoin的效率)
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年11月30日 下午7:58:04
*
*/
public class M {
public static void main(String[] args) {
var ps = Person.generatorPersons(10000000);
// 使用流
var start = new Date();
ConcurrentMap<String, List<Person>> collect = ps.parallelStream()
.collect(Collectors.groupingByConcurrent(p -> p.getArea()));
var end = new Date();
System.out.println(collect.size() + ":Stream::Time:" + (end.getTime() - start.getTime()));
// 使用fork/join框架
start = new Date();
var forkjoinMap = new ConcurrentHashMap<String, ConcurrentLinkedDeque<Person>>();
var personMapTask = new PersonMapTask(ps, forkjoinMap);
ForkJoinPool.commonPool().invoke(personMapTask);
end = new Date();
System.out.println(forkjoinMap.size() + ":ForkJoinPool::Time:" + (end.getTime() - start.getTime()));
}
}
二、Person类
package xyz.jangle.thread.test.nxi_13.streamvsforkjoin;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Model
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年11月30日 下午7:30:02
*
*/
public class Person {
private String name;
private String area;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
public static List<Person> generatorPersons(int size){
String[] names = {"A","B","C"};
String[] areas = {"北","上","深","杭"};
var persons = new ArrayList<Person>();
var random = new Random();
for (int i = 0; i < size; i++) {
var p = new Person();
p.setName(names[random.nextInt(names.length)]);
p.setArea(areas[random.nextInt(areas.length)]);
persons.add(p);
}
return persons;
}
}
三、forkjoin框架的任务
package xyz.jangle.thread.test.nxi_13.streamvsforkjoin;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.RecursiveAction;
/**
* forkjoin框架的任务
* @author jangle
* @email jangle@jangle.xyz
* @time 2020年11月30日 下午7:39:42
*
*/
public class PersonMapTask extends RecursiveAction {
/**
*
*/
private static final long serialVersionUID = 1L;
private List<Person> persons;
private ConcurrentHashMap<String, ConcurrentLinkedDeque<Person>> personMap;
public PersonMapTask(List<Person> persons, ConcurrentHashMap<String, ConcurrentLinkedDeque<Person>> personMap) {
super();
this.persons = persons;
this.personMap = personMap;
}
@Override
protected void compute() {
if (persons.size() < 1000) {
for (Person person : persons) {
ConcurrentLinkedDeque<Person> personList = personMap.computeIfAbsent(person.getArea(),
area -> new ConcurrentLinkedDeque<Person>());
personList.add(person);
}
return;
}
var t1 = new PersonMapTask(persons.subList(0, persons.size() / 2), personMap);
var t2 = new PersonMapTask(persons.subList(persons.size() / 2, persons.size()), personMap);
invokeAll(t1, t2);
}
}
四、执行结果
4:::Time:872
4:::Time:624
五、总结
两个解决方案的效率相近,forkjoin框架略高于Stream。但是,Stream使用方便,可以节省开发时间。