已使用多线程的几种方式
1、异步线程池的调用 无返回值
通过使用CompletableFuture来直接通过函数式接口调用。
//无返回值的异步调用
CompletableFuture.runAsync(() -> xxxService.selectXxx(param));
2、异步线程池的调用 有返回值
//在使用前,尽量去显式的调用线程池。
//显式生命线程池 p:本处最好显式声明,避免默认线程池耗尽CPU资源导致整体服务阻塞
ExecutorService executor = Executors.newFixedThreadPool(30);
使用有返回值的异步线程任务,并且当该线程执行完任务后,继续使用该线程去完成另一个任务。
CompletableFuture<List<HashDto>>xxxFuture = CompletableFuture.supplyAsync(() -> mapper.selectXxx(param1, param2,), executorService).whenComplete((b, e)->currentHashMap.put("xxx", b));
//等待所有线程执行完毕
//等待各子线程执行完成-阻塞式集成
CompletableFuture.allOf(xxxFuture, xxx2Future).get();
//最终在结束完任务后,再次手动调用线程池结束进程
finally {
if (null != executorService){
executorService.shutdown();
}
3、线程池的调用
直接使用executorService对象创建出来的对象
//开始多线程执行
ExecutorService executor = Executors.newFixedThreadPool(5);
//开始线程执行
executor.execute(() -> {
methodXxx(param));
methodXxx(param));
});
4、等待线程池的调用
ExecutorService + Future的组合
//先创建线程池
ExecutorService executor = Executors.newCachedThreadPool();
//创建future对象
Future<Object> info= null;
//执行future任务 有返回值的
try {
info= executor.submit(()->mapper.getXxxInfo(param););
} catch (Exception e) {
log.error("查询xx错误");
}
//确保所有任务执行结束
while(true){
if(executor.isTerminated()){
System.out.println("所有的子线程都结束了!");
break;
}
}
//最后获取异步任务的调用结束
xxxInfo.addAll((List<HashDto>) info.get());
在开发中,异步调用是不可避免的,学会使用异步调用能够提高接口的性能,在工作中能够带来很大的便利。但是现今为止,博主还只是停留在表面,没有去深入研究这些技术背后的原理,我想下一次发表博客的时候,就是我来阐述这些技术底层原理的时候!共勉!