之前的多线程处理
Runnable --> Void
Callable --> Future (get() 阻塞等待结果,或者while一直等待结果)
现在的异步编程
等结果完成后,自动触发回调方法。
CompletableFunction
a) 提供要运行的任务
- runAsync 无返回结果
- supplyAsync 有返回结果
b)任务完成后触发
- thenRun 完成任务时没有结果,然后接着运行下一个任务
- thenAccept 完成任务时有结果,处理该结果不用返回数据。
- thenApply 完成任务时有结果,处理改结果并返回新的数据。
c) 处理执行流程中碰到的异常
- exceptionally 当异常情况发生时,处理异常信息。
- handle 数据和异常同时由handle函数处理。
Testing Code:
package com.coupang.flink;
import org.junit.Test;
import java.time.LocalDateTime;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
* description: TODO
*
* @author adore.chen
* @date 2022-11-18
*/
public class CompletableFutureTest {
@Test
public void runAsync() {
CompletableFuture<Void> completableFuture = CompletableFuture
.runAsync(() -> {
System.out.println("First Runnable Task ... at " + LocalDateTime.now());
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
})
.thenRun(() -> System.out.println("Second Runnable Task ... at " + LocalDateTime.now()));
completableFuture.join();
System.out.println("Main thread finished! ");
}
@Test
public void runAsyncException() {
CompletableFuture<Void> completableFuture = CompletableFuture
.runAsync(() -> {
System.out.println("First Runnable Task ... at " + LocalDateTime.now());
throw new IllegalArgumentException("Unknown exception ...");
})
.thenRun(() -> System.out.println("Second Runnable Task ... at " + LocalDateTime.now()))
.exceptionally(e -> {
System.out.println("meet some exception");
e.printStackTrace(System.err);
return null;
});
completableFuture.join();
System.out.println("Main thread finished! ");
}
@Test
public void supplyAsync() {
CompletableFuture<Void> completableFuture = CompletableFuture
.supplyAsync( () -> {
System.out.println("First Callable Task ... at " + LocalDateTime.now());
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "First Result";
})
.thenAccept(r -> {
System.out.println("Second Callabe Task ... at " + LocalDateTime.now());
System.out.println("Received result from First Callable: " + r);
});
completableFuture.join();
System.out.println("Main Thread Finished");
}
@Test
public void supplyAsyncResult() throws ExecutionException, InterruptedException {
CompletableFuture<String> completableFuture = CompletableFuture
.supplyAsync( () -> {
System.out.println("First Callable Task ... at " + LocalDateTime.now());
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "First Result";
})
.thenApply(r -> {
System.out.println("Second Callabe Task ... at " + LocalDateTime.now());
System.out.println("Received result from First Callable: " + r);
return "Second Task Result";
});
System.out.println("Main Thread Finished with Result: " + completableFuture.get());
}
public static void supplyAsyncHandle() throws ExecutionException, InterruptedException {
CompletableFuture<String> completableFuture = CompletableFuture
.supplyAsync( () -> {
System.out.println("First Callable Task ... at " + LocalDateTime.now());
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "First Result";
})
.thenApply(r -> {
System.out.println("Second Callabe Task ... at " + LocalDateTime.now());
System.out.println("Received result from First Callable: " + r);
return "Second Task Result";
})
.handle((data, e) -> {
System.out.println("get result from first task, result: " + data);
if (e != null) {
e.printStackTrace();
}
return "handle over";
})
;
System.out.println("Main Thread Finished with Result: " + completableFuture.get());
}
@Test
public void supplyAsyncHandleException() throws ExecutionException, InterruptedException {
CompletableFuture<String> completableFuture = CompletableFuture
.supplyAsync( () -> {
System.out.println("First Callable Task ... at " + LocalDateTime.now());
throw new IllegalArgumentException("Unkown Exception !!!");
})
.thenApply(r -> {
System.out.println("Second Callabe Task ... at " + LocalDateTime.now());
System.out.println("Received result from First Callable: " + r);
return "Second Task Result";
})
.handle((data, e) -> {
System.out.println("get result from first task, result: " + data);
if (e != null) {
e.printStackTrace();
}
return "handle over";
})
;
System.out.println("Main Thread Finished with Result: " + completableFuture.get());
}
}
commonPool: CPU密集型任务使用
exectorService: IO密集型任务使用
生产问题之CompletableFuture默认线程池踩坑,请务必自定义线程池 - 穿黑风衣的牛奶 - 博客园
CompletableFuture避坑1——需要自定义线程池 - 简书
自定义ThreadPool
https://blog.youkuaiyun.com/ALiangXiu/article/details/125007768
java - 使用CompletableFuture配合自定义线程池进行多任务并行处理 - 个人文章 - SegmentFault 思否
本文详细介绍了Java中的CompletableFuture类,包括其基本用法如runAsync和supplyAsync,以及如何通过thenRun、thenAccept和thenApply来定义任务执行后的操作。此外还讲解了如何处理异常和使用自定义线程池。
5万+

被折叠的 条评论
为什么被折叠?



