CompletableFuture基本用法
CompletableFuture 提供了四个静态方法来创建一个异步操作,其他方法有兴趣的同学可以了解一下。
默认情况下 CompletableFuture 会使用公共的 ForkJoinPool 线程池,这个线程池默认创建的线程数是 CPU 的核数 如果所有 CompletableFuture 共享一个线程池,那么一旦有任务执行一些很慢的 I/O 操作,就会导致线程池中所有线程都阻塞在 I/O 操作上,从而造成线程饥饿,进而影响整个系统的性能。所以,强烈建议你要根据不同的业务类型创建不同的线程池,以避免互相干扰。
1.runAsync方法不提供返回值
public static CompletableFuture<Void> runAsync(Runnable runnable) {
return asyncRunStage(asyncPool, runnable);
}
public static CompletableFuture<Void> runAsync(Runnable runnable,
Executor executor) {
return asyncRunStage(screenExecutor(executor), runnable);
}
2.supplyAsync方法是带返回值的
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
return asyncSupplyStage(asyncPool, supplier);
}
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
Executor executor) {
return asyncSupplyStage(screenExecutor(executor), supplier);
}
3.runAsync用法
//获取线程数量
private static final int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
//创建一个线程池(根据实际的业务需求)
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(AVAILABLE_PROCESSORS, AVAILABLE_PROCESSORS, 1, TimeUnit.MINUTES,
new LinkedBlockingQueue<>(10), new ThreadPoolExecutor.CallerRunsPolicy());
/**
* 异步推送方法
*/
public void asyncMethod(){
//设置子线程可见
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
CompletableFuture.runAsync(() -> {
try {
log.info("开始执行异步代码......");
} catch (Exception e) {
log.error("异步代码异常:{}", e.getMessage());
e.printStackTrace();
}
}, executor);
}
4.supplyAsync用法
//获取线程数量
private static final int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
//创建一个线程池(根据实际的业务需求)
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(AVAILABLE_PROCESSORS, AVAILABLE_PROCESSORS, 1, TimeUnit.MINUTES,
new LinkedBlockingQueue<>(10), new ThreadPoolExecutor.CallerRunsPolicy());
/**
* 异步推送方法
*/
public void asyncMethod(){
//设置子线程可见
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
CompletableFuture<Long> future = CompletableFuture.supplyAsync(() -> {
try {
log.info("开始执行异步代码......");
} catch (Exception e) {
log.error("异步代码异常:{}", e.getMessage());
e.printStackTrace();
}
return null;
}, executor);
future.get();//获取返回值
}
循环线程获取返回值
public static void main(String[] args) throws ExecutionException, InterruptedException {
List<CompletableFuture<?>> futures = new ArrayList<>();
long start = System.currentTimeMillis();
for (int i = 0; i < 9; i++) {
int finalI = i;
futures.add(CompletableFuture.supplyAsync(() ->
{
try {
Thread.sleep(1000);
System.out.println("线程:CompletableFuture" + Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
return finalI;
}
));
}
//等待全部完成
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
//获取内容
for (CompletableFuture<?> future : futures) {
try {
Object s = future.get();
System.out.println(s);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("主线程:" + Thread.currentThread().getName());
System.out.println("cost" + (end - start));
}