利用FutureTask和ExecutorService实现一个任务拆分成多个任务,实现性能提高

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

业务场景:本地服务开发的时候,本地有个H服务,H想要查询一个展示数据的列表,就远程调用了A服务,A服务需要远程调用B服务,拿到一个list,拿到List之后,需要循环这个list,然后对List中的每个值进行循环,调用C服务和D服务 获得真正需要的数据。

遇到的问题:由于A服务拿到的List可能会比较大!!!估计在1000左右,然后如果单线程执行,需要循环这个list,然后针对list里的每一项,再去调用C和D服务,虽然单个调用比较快,但是因为是跨服务调用,循环1000次,会导致H服务这边远程调用超时,这种情况下造成查询不稳定。经常出现timeout

目前的解决方案:把这个大List进行拆分,然后多线程并发操作,以提升性能,降低远程调用的耗时。

期待反馈:希望大家看完后,能提出更有效的解决方案。

示例代码如下:

package test11;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

/** 
 * @author : mingwu.lxm
 * @version 创建时间:2016年1月5日 下午8:23:09 
 * 类说明  解决计算一个类的两个数相加,放到sum类中
 */
public class TestFutureTask {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		int size =6;
		
		List userInfoList = new ArrayList();
		//存储本地串行计算花费的时间
		List retInfoList1 = new ArrayList();
		//存储多线程计算花费的时间
		List retInfoList2 = new ArrayList();
		
		for (int i = 0; i < 1000; i++) {
			UserInfo uc = new UserInfo();
			uc.setMoneyA((int) (Math.random()*100));
			uc.setMoneyB((int) (Math.random()*100));
			userInfoList.add(uc);
		}
		//准备要执行的数据,数据整备完毕
		
		
		ExecutorService es = Executors.newFixedThreadPool(100);
		Long aDateLong = System.currentTimeMillis();
		for (int i = 0; i < userInfoList.size(); i++) {
			int sum = userInfoList.get(i).getMoneyA()+userInfoList.get(i).getMoneyB();
			userInfoList.get(i).setSumNum(sum);
			retInfoList1.add(userInfoList.get(i));
			//线程睡眠以模仿计算消耗的时间
			Thread.sleep(1);
		}
		Long bDateLong = System.currentTimeMillis();
		System.out.println("串行进行的耗时:"+ (bDateLong-aDateLong));
		
		List> subTaskList = new ArrayList>();
		//切分任务
		for (int i =0 ;i<=userInfoList.size();i=i+size) {
			subTaskList.add(userInfoList.subList(i, Math.min(i+size, userInfoList.size())));
		}
		Long aDateLong2 = System.currentTimeMillis();
		
		//这个list是专门用来保存所有的future的,先把所有任务全部扔出去执行,这时候不管结果
		List>> tasklist = new ArrayList>>();
	   for (List alist : subTaskList) {
		  FutureTask> task = new FutureTask>(new SumJob(alist));
		  es.execute(task);
		  tasklist.add(task);
	}
	   //拿到所有的结果
	   for (FutureTask> futureTask : tasklist) {
		   retInfoList2.addAll(futureTask.get());
		
	}
	   
	   Long bDateLong2 = System.currentTimeMillis();
	   System.out.println("多线程拆分后耗时:"+ (bDateLong2-aDateLong2));
	   System.out.println(retInfoList1.size());
	   System.out.println(retInfoList2.size());
		
	}


}
//求和的线程任务
class SumJob implements Callable>{
	private List sumList=null;
	public SumJob(List sumList) {
		super();
		this.sumList = sumList;
	}

	@Override
	public List call() throws Exception {
		for (int i = 0; i < sumList.size(); i++) {
			int sum = sumList.get(i).getMoneyA()+sumList.get(i).getMoneyB();
			sumList.get(i).setSumNum(sum);
			//线程睡眠以模仿计算消耗的时间
			Thread.sleep(1);
		}
		return sumList;
	}
	
}


转载于:https://my.oschina.net/91jason/blog/598332

你可能感兴趣的:(利用FutureTask和ExecutorService实现一个任务拆分成多个任务,实现性能提高)