关于使用异步编排CompletableFuture的测试
public class CompletableFutureTest {
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor executor = new ThreadPoolExecutor(8, 16, 10,
TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(1),new ThreadPoolExecutor.DiscardPolicy());
List<CompletableFuture<Integer>> futureList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
int finalI = i;
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("异步编排任务:" + finalI + "开始执行");
try {
Thread.sleep(1000 * finalI);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("异步编排任务:" + finalI + "睡眠结束,即将完成");
return finalI;
}, executor);
futureList.add(future);
}
System.out.println("============== 异步任务编排完成 =================");
Thread.sleep(10000);
for (int i = 0; i < 100; i++) {
CompletableFuture<Integer> future = futureList.get(i);
try {
future.get(10, TimeUnit.MILLISECONDS);
Integer futureNow = future.getNow(-1);
System.out.println("任务-" + i + "-异步执行结果为" + futureNow);
} catch (InterruptedException e) {
System.out.println("异常1");
future.cancel(true);
System.out.println("任务-" + i + "-是否取消" + future.isCancelled());
} catch (ExecutionException e) {
System.out.println("异常2");
future.cancel(true);
System.out.println("任务-" + i + "-是否取消" + future.isCancelled());
} catch (TimeoutException e) {
System.out.println("任务-" + i + "异常3");
future.cancel(true);
System.out.println("任务-" + i + "-是否取消" + future.isCancelled());
}
}
}
}
执行结果
com.test.threadTest.CompletableFutureTest
异步编排任务:0开始执行
异步编排任务:5开始执行
异步编排任务:0睡眠结束,即将完成
异步编排任务:6开始执行
异步编排任务:4开始执行
异步编排任务:1开始执行
异步编排任务:8开始执行
异步编排任务:7开始执行
异步编排任务:2开始执行
异步编排任务:3开始执行
异步编排任务:12开始执行
============== 异步任务编排完成 =================
异步编排任务:9开始执行
异步编排任务:13开始执行
异步编排任务:17开始执行
异步编排任务:10开始执行
异步编排任务:14开始执行
异步编排任务:16开始执行
异步编排任务:11开始执行
异步编排任务:1睡眠结束,即将完成
异步编排任务:15开始执行
异步编排任务:2睡眠结束,即将完成
异步编排任务:3睡眠结束,即将完成
异步编排任务:4睡眠结束,即将完成
异步编排任务:5睡眠结束,即将完成
异步编排任务:6睡眠结束,即将完成
异步编排任务:7睡眠结束,即将完成
异步编排任务:8睡眠结束,即将完成
异步编排任务:9睡眠结束,即将完成
异步编排任务:10睡眠结束,即将完成
任务-0-异步执行结果为0
任务-1-异步执行结果为1
任务-2-异步执行结果为2
任务-3-异步执行结果为3
任务-4-异步执行结果为4
任务-5-异步执行结果为5
任务-6-异步执行结果为6
任务-7-异步执行结果为7
任务-8-异步执行结果为8
任务-9-异步执行结果为9
任务-10-异步执行结果为10
任务-11异常3
任务-11-是否取消true
任务-12异常3
任务-12-是否取消true
任务-13异常3
任务-13-是否取消true
任务-14异常3
任务-14-是否取消true
任务-15异常3
任务-15-是否取消true
任务-16异常3
任务-16-是否取消true
任务-17异常3
任务-17-是否取消true
任务-18异常3
任务-18-是否取消true
任务-19异常3
任务-19-是否取消true
任务-20异常3
任务-20-是否取消true
任务-21异常3
任务-21-是否取消true
任务-22异常3
任务-22-是否取消true
任务-23异常3
任务-23-是否取消true
任务-24异常3
任务-24-是否取消true
任务-25异常3
任务-25-是否取消true
任务-26异常3
任务-26-是否取消true
任务-27异常3
任务-27-是否取消true
任务-28异常3
任务-28-是否取消true
任务-29异常3
任务-29-是否取消true
任务-30异常3
任务-30-是否取消true
任务-31异常3
任务-31-是否取消true
任务-32异常3
任务-32-是否取消true
任务-33异常3
任务-33-是否取消true
任务-34异常3
任务-34-是否取消true
任务-35异常3
任务-35-是否取消true
任务-36异常3
任务-36-是否取消true
任务-37异常3
任务-37-是否取消true
任务-38异常3
任务-38-是否取消true
任务-39异常3
任务-39-是否取消true
任务-40异常3
任务-40-是否取消true
任务-41异常3
任务-41-是否取消true
任务-42异常3
任务-42-是否取消true
任务-43异常3
任务-43-是否取消true
任务-44异常3
任务-44-是否取消true
任务-45异常3
任务-45-是否取消true
任务-46异常3
任务-46-是否取消true
任务-47异常3
任务-47-是否取消true
任务-48异常3
任务-48-是否取消true
任务-49异常3
任务-49-是否取消true
任务-50异常3
任务-50-是否取消true
任务-51异常3
任务-51-是否取消true
任务-52异常3
任务-52-是否取消true
任务-53异常3
任务-53-是否取消true
任务-54异常3
任务-54-是否取消true
任务-55异常3
任务-55-是否取消true
任务-56异常3
任务-56-是否取消true
任务-57异常3
任务-57-是否取消true
任务-58异常3
任务-58-是否取消true
任务-59异常3
任务-59-是否取消true
任务-60异常3
任务-60-是否取消true
任务-61异常3
任务-61-是否取消true
任务-62异常3
任务-62-是否取消true
任务-63异常3
任务-63-是否取消true
任务-64异常3
任务-64-是否取消true
任务-65异常3
任务-65-是否取消true
任务-66异常3
任务-66-是否取消true
任务-67异常3
任务-67-是否取消true
任务-68异常3
任务-68-是否取消true
任务-69异常3
任务-69-是否取消true
任务-70异常3
任务-70-是否取消true
任务-71异常3
任务-71-是否取消true
任务-72异常3
任务-72-是否取消true
任务-73异常3
任务-73-是否取消true
异步编排任务:11睡眠结束,即将完成
任务-74异常3
任务-74-是否取消true
任务-75异常3
任务-75-是否取消true
任务-76异常3
任务-76-是否取消true
任务-77异常3
任务-77-是否取消true
任务-78异常3
任务-78-是否取消true
任务-79异常3
任务-79-是否取消true
任务-80异常3
任务-80-是否取消true
任务-81异常3
任务-81-是否取消true
任务-82异常3
任务-82-是否取消true
任务-83异常3
任务-83-是否取消true
任务-84异常3
任务-84-是否取消true
任务-85异常3
任务-85-是否取消true
任务-86异常3
任务-86-是否取消true
任务-87异常3
任务-87-是否取消true
任务-88异常3
任务-88-是否取消true
任务-89异常3
任务-89-是否取消true
任务-90异常3
任务-90-是否取消true
任务-91异常3
任务-91-是否取消true
任务-92异常3
任务-92-是否取消true
任务-93异常3
任务-93-是否取消true
任务-94异常3
任务-94-是否取消true
任务-95异常3
任务-95-是否取消true
任务-96异常3
任务-96-是否取消true
任务-97异常3
任务-97-是否取消true
任务-98异常3
任务-98-是否取消true
任务-99异常3
任务-99-是否取消true
异步编排任务:12睡眠结束,即将完成
异步编排任务:13睡眠结束,即将完成
异步编排任务:14睡眠结束,即将完成
异步编排任务:16睡眠结束,即将完成
异步编排任务:15睡眠结束,即将完成
异步编排任务:17睡眠结束,即将完成
根据以上执行结果 可以看出,
任务1-10 是正常执行完成,且有通过 future.getNow
方法取到任务执行完成的返回结果值,
而任务11-17 是已经被CompletableFuture
编排使用 executor 进行执行,但是执行未结束,但是由于任务 future.get(10, TimeUnit.MILLISECONDS);
任务执行超时,抛出TimeOut异常 然后执行future.cancel(true);
取消逻辑,但是可以看到 在控制台打印的日志看到,最后仍有以下结果,说明,当线程池的线程已经开始执行11-17的任务时,future.cancel(true);
执行的任务取消逻辑 只是取消了CompletableFuture
编排里的任务,但是对于已经被线程执行中的任务,这个取消接口不能去终止这个线程,从而去释放线程资源。
异步编排任务:12睡眠结束,即将完成
异步编排任务:13睡眠结束,即将完成
异步编排任务:14睡眠结束,即将完成
异步编排任务:16睡眠结束,即将完成
异步编排任务:15睡眠结束,即将完成
异步编排任务:17睡眠结束,即将完成
而下面的大部分没有被CompletableFuture
丢进executor
执行的任务,直接取消,则相当于是在CompletableFuture
的里面取消掉,不在被安排线程进行执行。
所以此时即使抛异常,取消11-17任务,但是 线程资源仍然没有被释放。