文章场景
我最近在做大屏可视化,因此有时候一个折线图显示很多维度的信息,每个维度极端都需要计算好几秒,如果用同步计算,那耗时就是每个维度计算的时间之和,因此很有必要使用异步请求。
配置工作
启动类添加注解
//能够使用异步
@EnableAsync
模拟请求
我们先写一个controller,供测试请求
代码如下:
.
@RestController
@RequestMapping("test")
@CrossOrigin
public class TestController {
//添加日志类
Logger logger = LoggerFactory.getLogger(TestController.class);
//注入实现类
@Autowired
private TestImpl tests;
//异步测试请求
@GetMapping(value = "/async")
@ApiOperation(value = "测试异步请求")
public HttpResult async() {
//存放返回结果
List<String> result = new ArrayList<>();
//辅助类,允许多个线程一直等待
CountDownLatch countDownLatch = new CountDownLatch(6);
//调用实现类的方法,每个方法阻塞3秒
tests.getString(result,countDownLatch);
tests.getString(result,countDownLatch);
tests.getString(result,countDownLatch);
tests.getString(result,countDownLatch);
tests.getString(result,countDownLatch);
tests.getString(result,countDownLatch);
try {
//辅助类等待结果,直到线程都返回结果或者到100秒不再等待
countDownLatch.await(100, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
//把返回的结果打印出来
return HttpResult.ok(JSONObject.toJSONString(result));
}
}
创建阻塞请求
@Service
public class TestImpl {
//异步方法注解,也可以添加在类上,表示所有方法都是异步方法
@Async
public void getString(List<String> result, CountDownLatch countDownLatch) {
try {
//阻塞3秒
Thread.sleep(3000);
//结果放入列表,传回请求
result.add("hello");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//线程减一
countDownLatch.countDown();
}
}
}
测试请求
启动项目后,在浏览器测试请求:
http://localhost:8003/test/async
预期结果
如果是不用异步,应该是需要18秒才能返回结果,但现在应该是3秒多返回结果:
{"code":"000000","message":"[null,\"hello\",\"hello\",\"hello\",\"hello\",\"hello\"]","data":null}
结语
异步确实可以提高效率,但对于返回的结果记得验证,欢迎大家一起讨论,共同学习