1.调用CompletableFuture的静态方法创建一个线程来执行任务。
//传入一个Runnable接口。
public static CompletableFuture<Void> runAsync(Runnable runnable)
//传入一个Runnable接口,指定使用一个线程池来执行该任务。
public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor)
//传入一个Supplier接口,该方法可以返回线程的执行结果。
public static CompletableFuture<Void> supplyAsync(Supplier<U> f)
//传入一个Supplier接口,指定使用一个线程池来执行该任务,该方法可以返回线程的执行结果。
public static CompletableFuture<Void> supplyAsync(Supplier<U> f,Executor executor)
2.如果需要在一个线程执行完成后紧接着再做一些处理。
//在task01执行完成后,执行task02,使用ForkJoin线程池
CompletableFuture<Integer> task01 = CompletableFuture.supplyAsync(() -> {
System.out.println("菜鸡学编程");
return 1;
});
//在task01执行完成后,执行task02,使用与task01同一个线程池
task01.thenRun(()->{
System.out.println("执行完task01后,紧接着执行task02");
})
//在task01执行完成后,执行task02,使用ForkJoin线程池
task01.thenRunAsync(()->{
System.out.println("执行完task01后,紧接着执行task02");
})
//在task01执行完成后,执行task02,使用自定义线程池
task01.thenRunAsync(()->{
System.out.println("执行完task01后,紧接着执行task02");
},pool);
//在task01执行完成后,接收task01的执行结果作为执行task02的入参,使用与task01同一个线程池
task01.thenAccept((value)->{
System.out.println(value);
});
//在task01执行完成后,接收task01的执行结果作为执行task02的入参,使用ForkJoin线程池
task01.thenAcceptAsync((value)->{
System.out.println(value);
});
//在task01执行完成后,接收task01的执行结果作为执行task02的入参,使用自定义线程池
task01.thenAcceptAsync((value)->{
System.out.println(value);
},pool);
//在task01执行完成后,接收task01的执行结果作为执行task02的入参,并且需要返回一个值,使用与task01同一个线程池
task01.thenApply((value)->{
return value+1;
});
//在task01执行完成后,接收task01的执行结果作为执行task02的入参,并且需要返回一个值,使用ForkJoin线程池
task01.thenApplyAsync((value)->{
return value+1;
});
//在task01执行完成后,接收task01的执行结果作为执行task02的入参,并且需要返回一个值,使用自定义线程池
task01.thenApplyAsync((value)->{
return value+1;
},pool);
3.异常回调
//执行任务一的异常回调
task01.whenComplete((value,ex)->{
//发生异常后,ex不为空
if(ex!=null){
System.out.println("出异常了");
}
else {
System.out.println(value);
}
//发生异常后会执行exceptionally回调
}).exceptionally((ex)->{
return 1;
});
4.等待执行完任务一与任务二后,接着再执行新的任务
CompletableFuture<Integer> task01 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(2L);
System.out.println("执行任务1");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 1;
});
CompletableFuture<Integer> task02 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1L);
System.out.println("执行任务2");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 2;
});
//执行完任务一与任务二后,接着再执行新的任务
CompletableFuture<Void> task03 = task02.runAfterBoth(task01, () -> {
System.out.println("执行任务3");
});
task03.get();
//执行完任务一与任务二后,接收任务一与任务二的返回值作为入参,执行新的任务
CompletableFuture<Void> task03 = task02.thenAcceptBoth(task01, (value01, value02) -> {
System.out.println("执行任务3输出结果:"+(value01 + value02));
});
task03.get();
//执行完任务一与任务二后,接收任务一与任务二的返回值作为入参,执行新的任务,并且有返回值
CompletableFuture<Integer> task03 = task02.thenCombine(task01, (value01, value02) -> {
return value01 + value02;
});
System.out.println("执行任务3返回结果:"+task03.get());
5.只要任务一与任务二其中一个完成,就执行任务三
//执行完任务一或者任务二后,接着再执行新的任务
CompletableFuture<Void> task03 = task01.runAfterEither(task02, () -> {
System.out.println("执行任务3");
});
task03.get();
//执行完任务一或者任务二后,接收任务一或者任务二的返回值作为入参,执行新的任务
CompletableFuture<Void> task03 = task01.acceptEither(task02, (value) -> {
System.out.println(value);
});
task03.get();
//执行完任务一或者任务二后,接收任务一或者任务二的返回值作为入参,执行新的任务,并且有返回值
CompletableFuture<Integer> task03 = task01.applyToEither(task02, (value) -> {
System.out.println(value);
return value;
});
task03.get();
6.等待所有任务完成后,再执行新的任务
CompletableFuture<Integer> task01 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(2L);
System.out.println("执行任务1");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 1;
});
CompletableFuture<Integer> task02 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1L);
System.out.println("执行任务2");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 2;
});
CompletableFuture<Integer> task03 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1L);
System.out.println("执行任务3");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 3;
});
CompletableFuture<Void> allOf = CompletableFuture.allOf(task01, task02, task03);
allOf.get();
//走到这代表所有任务都完成了,获取三个任务的返回值
task01.get();
task02.get();
task03.get();
7.所有任务只要有一个执行完
CompletableFuture<Integer> task01 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(2L);
System.out.println("执行任务1");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 1;
});
CompletableFuture<Integer> task02 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1L);
System.out.println("执行任务2");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 2;
});
CompletableFuture<Integer> task03 = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(1L);
System.out.println("执行任务3");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 3;
});
CompletableFuture<Object> anyOf = CompletableFuture.anyOf(task01, task02, task03);
//走到这代表有一个任务完成了,获取任务的返回值
Object o = anyOf.get();
8.使用的注意事项:
- 当没有自定义线程池时,使用ForkJoinPool线程池,默认的线程数为cpu核数*2-1
- 使用自定义线程池时,最好使用抛出异常的拒绝策略。
- 调用get()方法时注意设置超时时间。