您的位置:首页 > 其它

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

2016-01-06 00:00 387 查看
摘要: 利用FutureTask和ExecutorService实现一个任务拆分成多个任务,多线程实现性能提

业务场景:本地服务开发的时候,本地有个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<UserInfo> userInfoList = new ArrayList<UserInfo>();
//存储本地串行计算花费的时间
List<UserInfo> retInfoList1 = new ArrayList<UserInfo>();
//存储多线程计算花费的时间
List<UserInfo> retInfoList2 = new ArrayList<UserInfo>();

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<List<UserInfo>> subTaskList = new ArrayList<List<UserInfo>>();
//切分任务
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<FutureTask<List<UserInfo>>> tasklist = new ArrayList<FutureTask<List<UserInfo>>>();
for (List<UserInfo> alist : subTaskList) {
FutureTask<List<UserInfo>> task = new FutureTask<List<UserInfo>>(new SumJob(alist));
es.execute(task);
tasklist.add(task);
}
//拿到所有的结果
for (FutureTask<List<UserInfo>> 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<List<UserInfo>>{
private List<UserInfo> sumList=null;
public SumJob(List<UserInfo> sumList) {
super();
this.sumList = sumList;
}

@Override
public List<UserInfo> 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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: