持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情
前面看了很多文章介绍CompletableFuture基本用法的,但一直没有自己动手敲过,所以总觉得差点什么,有点虚,
future
下面我们一步一步看下这个的使用,首先简单看下我们的很多情况下使用的是Future<输出对象> 来接收返回,然后get()结果,大概看个用例(第二个Future的submit就不写了)
ExecutorService es = Executors.newFixedThreadPool(2);
Future<String > a = es.submit(() -> {System.out.println("我在");
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("我在");
return "hello";
});
System.out.println(a.get(5,TimeUnit.SECONDS));
此处大概意思就是让线程执行6秒,但是我希望5秒就取到结果,很明显我是取不到结果的,会报错,但是这个线程的流程还是执行的最终的输出是
我在
Exception in thread "main" java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:205)
at com.xxx.Demo.main(Demo.java:44)我在
如果你给个7秒,那是可以正常输出的;但是这个获取返回结果是阻塞的,如果我们两个任务那么必须前面那个线程返回了后面的线程才能获取返回;对于我们性能要求严格的地方这个显然不能满足要求,我们就得换个接口看看了;
CompletableFuture
下面我们看看CompletableFuture如何进行操作的,首先看下大概的概念就是我们的线程任务执行完成后往往需要这个返回做下一步动作,但是我们不好阻塞进行呀,因此CompletableFuture提供了whenComplete方法进行下一步操作;
CompletableFuture<String> s1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("我在");
return "hello";
}).whenComplete((r, x) -> {
System.out.println(r);
});
相同的我们再定义一个s2,sleep时间短点,
CompletableFuture<String> s3 = s1.thenCombineAsync(s2, String::concat);
System.out.println(stringCompletableFuture2.get());
这样他们会各自执行自己的逻辑,执行完成后执行whenComplete进行后续操作,他们之间不会说获取值执行后续操作出现阻塞,
执行结果是
我在a
helloa
我在
hello
hellohelloa
当然我们可以在future的基础上做个鸡贼的操作,通过一个集合来接收批量执行的future返回体,这里注意下,不进行get操作这样就不会阻塞了,在我们的批量操作结束后进行遍历操作
在循环里进行get操作,如此按序操作也可以缓解get出现的阻塞情况
Future<AnaOut> future = threadPoolExecutor.submit(方法体);
futureMap.put(key, future);
以上就是使用future的改善方案,和CompletableFuture的一点小了解,好啦🥗🥗🥗;
结束结束,那就🛴🛴🛴