提前声明:本人CSDN上面所有的文章均是从知乎的本人账号文章中复制过来的,图片方面会有知乎的水印属于正常现象。
JDK1.8的更新内容很多,除了之前所说的StringJoiner之外还有这么一个简单方便的类:CompletableFuture。在这个类出现之前我们实现异步编程的话肯定是需要我们自己手动创建线程实现了,而这个类的作用就是帮助我们更加简单的实现异步编程的,具体使用方法见下文。
首先这个类虽然帮助我们实现的调用简单,但是该类并不在java.util包下,而是在JUC包下,下面直接切入正题。
这个类有两个常用的静态方法,supplyAsync、runAsync,这两个方法的区别是一个supplyAsync会有返回值,而runAsync没有返回值,返回值类型跟我们定义出来的对象类的泛型一致,具体见下图。
我们这里为了测试写出来的代码如下:(junit测试方法)
@Test
public void test13() {
try {
System.out.println(testAsync());
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
public String testAsync() throws ExecutionException, InterruptedException {
System.out.println("1");
//进入异步(创建新线程执行),改代码块下的代码会继续以当前线程继续执行
CompletableFuture<String> async = CompletableFuture.supplyAsync(() -> {
try {
System.out.println("3");
TimeUnit.SECONDS.sleep(3);
System.out.println("4");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "async";
});
System.out.println("2");
return async.get();
}
测试结果如下:
这时我们可以得知testAsync方法里的异步代码块看起来好像是在方法本体输出2之后才去执行的,然后我们在本体输出2之前添加一个线程睡眠方法,如下图。
然后输出内容就变成了这样,如下图。
由此可见该异步方法实在代码跑到的时候立即创建新线程执行的,也就是说这个时候主线程和异步线程在同时执行。这里再说一下,我再运行之后试了一下打印线程名称,执行我们方法本体内容的线程是main线程没问题,调用异步方法的线程名是这样的:ForkJoinPool.commonPool-worker-1,见名知意,这个异步方法的底层是用ForkJoinPool来创建新线程进行执行的,而Fork Join一般使用在大任务拆分小任务进行。举个例子:就比如给我们十套卷子让我们做,然后我们感觉太多了就找到五个朋友分发下去一起做,然后最终等所有人都做完了再交到我们手上,这样就极大的提升了效率。不过这里需要得知的是每个线程执行任务都是需要占用一部分系统资源的,所以我们就算如此使用的话异步方法创建太多了也不合适,这里简单了解下即可,之后如有兴趣的话会对该方法的底层代码进行剖析然后发布出来对应文章供各位参考的。
该文章仅供参考,如有错误或缺漏欢迎各位指点迷津。