在我们进行海量数据的处理时,如果通过传统的方式也就是同步的方式进行查询等操作,对用户的响应时间是不友好的。而引入线程异步操作之后,则会大大改善我们查询等操作消耗的时间。
我们同时对两个均含有10万条数据的表进行查询,未使用线程异步的代码如下:
public void unusedThread() {
long startTime = System.currentTimeMillis(); //获取开始时间
List<TbUser> tbUserList = tbUserService.list();
//获取user1
List<TbUser1> user1List = tbUser1Service.list();
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("未使用线程池查询所耗费的时间为:" + (endTime - startTime) + "ms");
}
耗时如下:
使用线程异步的代码:
public void usedThread() {
long startTime = System.currentTimeMillis(); //获取开始时间
TimeUnit unit;
BlockingQueue workQueue;
ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
10, 15, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(5),
new ThreadPoolExecutor.CallerRunsPolicy());
//异步执行
CompletableFuture<Void> addressFuture = CompletableFuture.runAsync(() -> {
List<TbUser> tbUserList = tbUserService.list();
}, executor);
//异步执行
CompletableFuture<Void> addressFuture1 = CompletableFuture.runAsync(() -> {
List<TbUser1> tbUser1List = tbUser1Service.list();
}, executor);
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("使用线程池查询所耗费的时间为:" + (endTime - startTime) + "ms");
耗时如下:
最终两者的耗时对比:
可以看出对于查询的操作,由于异步的线程,两个查询均不受到互相的影响,无需等待另外一个查询结束之后才会进行下一步的操作,同时我们也可以看出,这两个线程下的执行内容对后面的执行完全没有任何影响,但是在使用时一定要注意线程安全的问题。
下面补充一下CompletableFuture实现等待所有异步任务完成:
CompletableFuture<Void> all = CompletableFuture.allOf(addressFuture, addressFuture1);
all.join();