FutureTask与CountDownLatch的结合使用

现在有这样一个场景,用户下单服务(OrderServe)再下但之前需要调用用户服务验证用户信息,要调用账户服务验证账户,要调用贷款服务验证贷款信息,等等,这几个服务异步调用太慢,导致改下单服务非常慢,这几个验证之间有没有任何关联,最终结果所有验证结果都通过就算成功,有一个不通过就失败,则其他验证则立即结束返回失败,所以这几个验证可以同步进行 怎么来优化。
这里我结合FutureTaskCountDownLatch使用

3个服务类,这里只贴一个类 其他一样

/**
 * 模拟征信验证
 */
public class RemoteBankService {

    public boolean checkAuth(){
        boolean flag;

        System.out.println("征信验证 - 验证开始");
        try {
            Thread.sleep(30000);
            flag = true;
        } catch (InterruptedException e) {
            System.out.println("征信验证 - 验证终止");
            return false;
        }

        if(flag){
            System.out.println("征信验证 - 验证成功");
            return true;
        }
        else {
            System.out.println("征信验证 - 验证失败");
            return false;
        }
    }
}

3个线程 每个线程验证一个事情,这里只贴一个类,其他一样

/**
 * 征信验证
 */
public class RemoteBankCallable implements Callable<Boolean> {
    @Override
    public Boolean call() throws Exception {
        return new RemoteBankService().checkAuth();
    }
}

定义一个CheckFutureTask类集成FutureTask 重写done()方法

public class CheckFutureTask extends FutureTask<Boolean> {

    private volatile CountDownLatch latch;

    private final int number;

    public CheckFutureTask(Callable checkCallable, CountDownLatch latch, int number) {
        super(checkCallable);
        this.latch = latch;
        this.number = number;
    }

    @Override
    protected void done() {
        try {
            if(!get()){
                afterFail();
            }
        } catch (Exception e) {
            afterFail();
        } finally {
            latch.countDown();
        }
    }

    /**
     * 在失败后调用
     */
    private void afterFail(){
        for(int i = 0 ; i < number - 1 ; i++){
            latch.countDown();
        }
    }
}

定义一个线程工厂

public class MyThreadFactory implements ThreadFactory {

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    @Override
    public Thread newThread(Runnable r) {
        return new Thread(r,"myThread - " + atomicInteger.incrementAndGet());
    }
}

写个main方法 验证以下

public class MainTest {
    private static CountDownLatch latch;

    /**
     * 开始下单
     * @param args
     */
    public static void main(String[] args) {
        final int poolSize = 3;
        final int maxPoolSize = poolSize*3;

        ThreadPoolExecutor executor = new ThreadPoolExecutor(poolSize,maxPoolSize,1, TimeUnit.MINUTES,new LinkedBlockingDeque<>(),new MyThreadFactory());

        
         latch = new CountDownLatch(3);

        CheckFutureTask f1 = new CheckFutureTask(new RemoteLoanCallable(),latch,3);
        CheckFutureTask f2 = new CheckFutureTask(new RemotePassportCallable(),latch,3);
        CheckFutureTask f3 = new CheckFutureTask(new RemoteBankCallable(),latch,3);

        executor.execute(f1);
        executor.execute(f2);
        executor.execute(f3);

        try {

            latch.await();

            //latch 为0后 跳过等待,说明已经之心完毕,如果有一个返回false,则其他正在执行的线程需要终止,所以需要有一个取消操作
            f1.cancel(true);
            f2.cancel(true);
            f3.cancel(true);


            //判断结果
            if(!f1.get()){
                System.out.println(false);
                executor.shutdown();
                return;
            }

            if(!f2.get()){
                System.out.println(false);
                executor.shutdown();
                return;
            }

            if(!f3.get()){
                System.out.println(false);
                executor.shutdown();
                return;
            }

        } catch (Exception e) {
            System.out.println(false);
            executor.shutdown();
            return;
        }

        System.out.println(true);

        executor.shutdown();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值