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

本文介绍了一种通过将大型数据集拆分成较小部分并使用多线程处理来提高处理效率的方法。这种方法可以显著减少处理时间,尤其是在跨服务调用时。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

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

示例代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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;
     }
     
}




转自:http://my.oschina.net/91jason/blog/598332

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值