使用FutureTask执行并行耗时任务

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010180738/article/details/78453759

在实际开发中,一般任务都有串行和并行之分。比如走完A步骤之后才能在走B步骤,这个属于串行。比如登录注册操作,只有先获取验证码,然后在使用验证码登录。又比如为了获取一个商品的价格,我们可以从多个渠道获取,从不同渠道获取商品价格是属于并行任务的,多个渠道之间完全没有任何的关系。这个时候我们一般都要搜集结果。


FutureTask就是非常适合这种情景的。
主要api有get,run,cancel等方法,在jdk1.7之前是依赖AbstractQueuedSynchronizer来实现的,1.7之后是使用直接原子操作,使用状态volatile state控制,较之前的版本改进很大,效率提升很多。
FutureTask相关源码介绍文章:
http://blog.csdn.net/xxxzhi/article/details/51453438
http://blog.csdn.net/wojiaolinaaa/article/details/50434817
深入分析volatile:
https://www.jianshu.com/p/7798161d7472
使用例子:

1:一般都要讲耗时任务放入到线程池中执行,而不是每次自己新建一个线程,需要做到对线程大小的可控。每台服务器都有最大线程限制的,需要将线程数量调整到最优。

/**
     * 核心线程20个  最多50个线程  队列最大200,大于200的时候默认会抛出拒绝服务异常  
     */
private ThreadPoolExecutor exec = new ThreadPoolExecutor(20, 50, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(200));

//任务执行工具封装类

public class ThirdCarOffersWorker<T> implements Callable<T> {
    private ThirdCarInsureService carInsureService;
    private ReqCarOffersDto reqCarOffersDto;
    private UserVo userVo;

    public ThirdCarOffersWorker(ThirdCarInsureService carInsureService, ReqCarOffersDto reqCarOffersDto, UserVo userVo) {
        super();
        this.carInsureService = carInsureService;
        this.reqCarOffersDto = reqCarOffersDto;
        this.userVo = userVo;
    }

    @SuppressWarnings("unchecked")
    @Override
    public T call() throws Exception {
        // TODO Auto-generated method stub
        T t = null;
        t = (T) carInsureService.submitCarOffers(reqCarOffersDto, userVo);
        return t;
    }

}

//执行任务

List<AppResponseDto<ChannelQuotePriceIdDto>> resultList = new ArrayList<AppResponseDto<ChannelQuotePriceIdDto>>();
FutureTask<AppResponseDto<ChannelQuotePriceIdDto>> future= new FutureTask<AppResponseDto<ChannelQuotePriceIdDto>>(
                            new ThirdCarOffersWorker<AppResponseDto<ChannelQuotePriceIdDto>>(carInsureService, carOffersDto, userVo));
            futureTasks.add(futureTask);
            exec.submit(futureTask);

//获取结果

 // 获取结果
        for (FutureTask<AppResponseDto<ChannelQuotePriceIdDto>> tempFt : futureTasks) {
            try {
                resultList.add(tempFt.get());
            } catch (InterruptedException | ExecutionException e) {
                log.error("submitCarOffers Exception,Get CarOffers Result Error msg={}", e);
            }
        }

猜你喜欢

转载自blog.csdn.net/u010180738/article/details/78453759
今日推荐