Future实现多请求合并

Future实现多请求合并

场景

一般声情况下,如果使用 Future 请求,如果带有 get(timeout) 方式请求,超时后,其实真正的请求还是在后台继续请求的。现在要实现的是 使用 get(timeout) 方式超时之后 ,我们的后台请求也可以随之结束

实现

public class FutureProvider {

    private List<Future<?>> futures;

    public FutureProvider(int size) {
        futures = new ArrayList<>(size);
    }

    public <T> FutureProvider addFuture(Future<T> future) {
        futures.add(future);
        return this;
    }

    public void execute(long timeout, TimeUnit unit, Consumer<List<Object>> callback, CountDownLatch latch) throws TimeoutException,
            ExecutionException, InterruptedException {
        try {
            latch.await(timeout, unit);
        } catch (InterruptedException e) {
            // ignore...
        }
        boolean done = true;
        for (Future<?> future : futures) {
            if (!future.isDone()) {
                done = false;
                future.cancel(true);
                System.out.println("cancel " + future.hashCode());
            }
        }

        List<Object> result = new ArrayList<>();
        if (done) {
            for (Future<?> future : futures) {
                result.add(future.get(0, TimeUnit.SECONDS));
            }
            callback.accept(result);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        long l = System.currentTimeMillis();
        FutureProvider futureProvider = new FutureProvider(2);
        ExecutorService executorService = Executors.newFixedThreadPool(4);
        try {
            CountDownLatch latch = new CountDownLatch(2);
            futureProvider.addFuture(executorService.submit(() -> {
                System.out.println("1....start");
                try {
                    TimeUnit.SECONDS.sleep(15);
                } catch (InterruptedException e) {
                    System.out.println("1....on error");
                    Thread.currentThread().interrupt();
                }
                System.out.println("1....end");
                System.out.println(Thread.currentThread().getName() + " 耗时: " + (System.currentTimeMillis() - l) / 1000);
                latch.countDown();
                return "success";
            })).addFuture(executorService.submit(() -> {
                System.out.println("2....start");
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    System.out.println("2....on error");
                    Thread.currentThread().interrupt();
                }
                System.out.println("2....end");
                System.out.println(Thread.currentThread().getName() + " 耗时: " + (System.currentTimeMillis() - l) / 1000);
                latch.countDown();
                return 1;
            })).execute(6L, TimeUnit.SECONDS, list -> {
                System.out.println("正常结束" + list);
                System.out.println(Thread.currentThread().getName() + " 耗时: " + (System.currentTimeMillis() - l) / 1000);
            }, latch);
        } catch (Exception e) {
            System.out.println("main.....error" + e.getMessage());
            System.out.println("main 耗时: " + (System.currentTimeMillis() - l) / 1000);
        }
        TimeUnit.SECONDS.sleep(15);
        executorService.shutdownNow();

    }
}

结果:

1....start
2....start
2....end
pool-1-thread-2 耗时: 3
cancel 521645586
1....on error
1....end
pool-1-thread-1 耗时: 6

可以发现,任务2 正常结束,任务1睡眠超过6秒,最后也在6秒的时候被取消了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值