携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情
前言
在有些时候我们会碰见处理多个任务, 而几个任务之间又没有联系的情况, 这个时候使用串行处理就会非常的慢, 我们可以使用并行处理这多个任务并最终同步返回给客户端, 从而加快接口的返回速度
CompletableFuture
我们可以看到这是since 1.8的类, 即jdk1.8出的新的java util, 在juc包下. 具体其他用法不谈只看一下allOf方法.
用法
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@RestController
public class FutureController {
@GetMapping("hello")
public String hello() {
long start = System.currentTimeMillis();
sleep();
sleep();
sleep();
long end = System.currentTimeMillis();
return "hello(): 耗时" + (end - start) + "ms";
}
/**
* 模拟一个耗时的操作
*/
private void sleep() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("休眠结束!");
}
}
测试一下
可以看到模拟的耗时操作串行, 导致三秒返回结果
使用CompletableFuture.allOf()
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@RestController
public class FutureController {
@GetMapping("hello")
public String hello() {
long start = System.currentTimeMillis();
sleep();
sleep();
sleep();
long end = System.currentTimeMillis();
return "hello(): 耗时" + (end - start) + "ms";
}
@GetMapping("future")
public String future() {
long start = System.currentTimeMillis();
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.allOf(
CompletableFuture.runAsync(this::sleep),
CompletableFuture.runAsync(this::sleep),
CompletableFuture.runAsync(this::sleep)
);
try {
voidCompletableFuture.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
return "future(): 耗时" + (end - start) + "ms";
}
/**
* 模拟一个耗时的操作
*/
private void sleep() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("休眠结束!");
}
}
测试Future
可以看到返回变快
后记
这就是CompletableFuture.allOf()的用法了 如果是对数据库的操作, 建议优化点要放在数据库语句或索引的优化, 使用这种方式会加大数据库的压力, 尤其是并发量高的接口应该慎用.