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%: