jdk1.7推出的Fork/Join提高业务代码处理性能
jdk1.7之后推出了Fork/Join框架,其原理个人理解为:递归多线程并发处理业务代码,以下为我模拟我们公司业务代码做的一个案例,性能可提升75%:
**下边这个类是模拟现有业务代码写的**
package NoForkJoin;
import forkJoinTest.Row;
import forkJoinTest.Student;
import java.util.ArrayList;
import java.util.List;
/**
* @author liu_l
* @Title: ServiceImp
* @ProjectName workspace-idea
* @Description: TODO
* @date 2018/6/240:32
*/
public class ServiceImp {
public static void main(String[] args) throws InterruptedException {
long s0 = System.currentTimeMillis();
//造业务数据
List<Student> list = new ArrayList<Student>();
for (int i = 0; i < 10000; i++) {
Student student = new Student();
student.setName("test1" + i);
student.setSax("man");
student.setTall((double) i);
list.add(student);
}
//开始业务数据处理
List<Row> rows = new ArrayList<Row>();
for (int i = 0; i < 10000; i++) {
Student student = list.get(i);
//模拟一条业务数据处理需耗时1毫秒
Thread.sleep(1);
Row row = new Row();
row.put("name", student.getName());
row.put("sax", student.getSax());
row.put("tall", student.getTall());
rows.add(row);
}
System.out.println("共处理业务对象:" + rows.size() + "个");
System.out.println("共耗时:" + (System.currentTimeMillis() - s0) + "毫秒");
}
}
运行结果如图:
下面为采用fork/join框架来实现此功能:
student类:模拟业务对像
package forkJoinTest;
import java.io.Serializable;
/**
* @author liu_l
* @Title: Student
* @ProjectName workspace-idea
* @Description: TODO
* @date 2018/6/2323:03
*/
public class Student implements Serializable {
private String name;
private Double tall;
private String sax;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getTall() {
return tall;
}
public void setTall(Double tall) {
this.tall = tall;
}
public String getSax() {
return sax;
}
public void setSax(String sax) {
this.sax = sax;
}
}
rows继承与HashMap,将业务对象组装为map格式:
package forkJoinTest;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author liu_l
* @Title: Row
* @ProjectName workspace-idea
* @Description: TODO
* @date 2018/6/2323:06
*/
public class Row extends ConcurrentHashMap{
public Student Student;
}
**重点:Fork/Join框架处理业务代码:**
package forkJoinTest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.RecursiveTask;
/**
* @author liu_l
* @Title: ForkJoin
* @ProjectName workspace-idea
* @Description: TODO
* @date 2018/6/2323:09
*/
public class ForkJoinCode extends RecursiveTask<List<Row>>{
protected static int THREAD_HOLD = 50;
protected int start;//开始任务序号
protected int end;//结束任务序号
protected List<Student> datas;
/**
* @Description: TODO
* @param:
* @author liu-lei
* @date 2018/6/23 23:19
*/
public static ForkJoinCode getInstance(int start, int end, List<Student> datas){
ForkJoinCode forkJoinCode = new ForkJoinCode();
forkJoinCode.start = start;
forkJoinCode.end = end;
forkJoinCode.datas = datas;
return forkJoinCode;
}
@Override
protected List<Row> compute() {
List<Row> rows = new ArrayList<Row>();
boolean canCompute = (end - start) <= THREAD_HOLD;
if(canCompute){
for(int i = start; i <= end; i++){
tranfromT2Row(rows, i);
}
}else{
int middle = (start + end)/2;
ForkJoinCode leftForkJoin = ForkJoinCode.getInstance(start, middle, datas);
ForkJoinCode rightForkJoin = ForkJoinCode.getInstance(middle+1, end, datas);
leftForkJoin.fork();
rightForkJoin.fork();
List<Row> lResult = leftForkJoin.join();
List<Row> rResult = rightForkJoin.join();
rows.addAll(lResult);
rows.addAll(rResult);
}
return rows;
}
/**
* @Description: 业务代码处理
* @param:
* @author liu-lei
* @date 2018/6/24 0:33
*/
public void tranfromT2Row(List<Row> rows, int i){
Student student = datas.get(i);
Row row = new Row();
row.put("name", student.getName());
row.put("sax", student.getSax());
row.put("tall", student.getTall());
try {
//模拟业务数据处理需耗时5毫秒
Thread.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
rows.add(row);
};
Service方法进行调用:
package forkJoinTest;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
/**
* @author liu_l
* @Title: ServiceImp
* @ProjectName workspace-idea
* @Description: TODO
* @date 2018/6/240:12
*/
public class ServiceImp {
public static void main(String[] args) throws ExecutionException, InterruptedException {
long s0 = System.currentTimeMillis();
//造业务数据
List<Student> list = new ArrayList<Student>();
for(int i = 0; i < 10000; i ++){
Student student = new Student();
student.setName("test1" + i);
student.setSax("man");
student.setTall((double)i);
list.add(student);
}
//开始业务数据处理
ForkJoinPool pool = new ForkJoinPool();
ForkJoinCode studentForkJoinCode = ForkJoinCode.getInstance(0, list.size()-1, list);
Future<List<Row>> result = pool.submit(studentForkJoinCode);
System.out.println("共处理业务对象:" + result.get().size() + "个");
showPoolStates(pool);
System.out.println("共耗时:" + (System.currentTimeMillis() - s0) + "毫秒");
}
/**
* @Description: 监控Fork/Join池相关方法
* @param:
* @author liu-lei
* @date 2018/6/24 0:43
*/
private static void showPoolStates(ForkJoinPool pool){
System.out.println("*******************");
System.out.println("线程池的worker线程数量:" + pool.getPoolSize());
System.out.println("当前执行任务的线程数量:" + pool.getActiveThreadCount());
System.out.println("没有被阻塞正在工作的线程:" + pool.getRunningThreadCount());
System.out.println("已经提交给池还没有开始执行的任务数:" + pool.getQueuedSubmissionCount());
System.out.println("已经提交给池开始执行的任务数:" + pool.getQueuedTaskCount());
System.out.println("线程偷取任务数:" + pool.getStealCount());
}
}
测试结果如下:
讲个结果对比性能提升了63%: