|
@@ -0,0 +1,42 @@
|
|
|
|
|
+package space.anyi;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
|
|
+import java.util.concurrent.Executors;
|
|
|
|
|
+
|
|
|
|
|
+public class Cf09_CustomExecutor {
|
|
|
|
|
+ public static void main(String[] args) throws Exception {
|
|
|
|
|
+ // 不指定线程池时,默认全部任务都跑在 ForkJoinPool.commonPool 上
|
|
|
|
|
+ CompletableFuture<String> defaultOne = CompletableFuture.supplyAsync(() -> {
|
|
|
|
|
+ System.out.println("默认线程池: " + Thread.currentThread().getName());
|
|
|
|
|
+ return "OK";
|
|
|
|
|
+ });
|
|
|
|
|
+ defaultOne.join();
|
|
|
|
|
+
|
|
|
|
|
+ // 重活建议显式指定自定义线程池,避免抢占公共池
|
|
|
|
|
+ ExecutorService pool = Executors.newFixedThreadPool(4);
|
|
|
|
|
+ CompletableFuture<String> custom = CompletableFuture.supplyAsync(() -> {
|
|
|
|
|
+ System.out.println("自定义池 supplyAsync: " + Thread.currentThread().getName());
|
|
|
|
|
+ return "结果";
|
|
|
|
|
+ }, pool).thenApplyAsync(r -> {
|
|
|
|
|
+ System.out.println("自定义池 thenApplyAsync: " + Thread.currentThread().getName());
|
|
|
|
|
+ return r + " 加工完成";
|
|
|
|
|
+ }, pool);
|
|
|
|
|
+ System.out.println("最终结果: " + custom.join());
|
|
|
|
|
+ pool.shutdown();
|
|
|
|
|
+
|
|
|
|
|
+ // 关键区别: 不带 Async 后缀的方法,新任务在哪执行由"触发者"所在的线程决定,
|
|
|
|
|
+ // 一般沿用前一个任务的执行线程;带 Async 且不传池子时,提交到 commonPool
|
|
|
|
|
+ CompletableFuture<String> noAsync = CompletableFuture.supplyAsync(() -> {
|
|
|
|
|
+ System.out.println("supplyAsync : " + Thread.currentThread().getName());
|
|
|
|
|
+ return "r";
|
|
|
|
|
+ }).thenApply(r -> {
|
|
|
|
|
+ System.out.println("thenApply(无Async) : " + Thread.currentThread().getName());
|
|
|
|
|
+ return r;
|
|
|
|
|
+ }).thenApplyAsync(r -> {
|
|
|
|
|
+ System.out.println("thenApplyAsync(无池): " + Thread.currentThread().getName());
|
|
|
|
|
+ return r;
|
|
|
|
|
+ });
|
|
|
|
|
+ noAsync.join();
|
|
|
|
|
+ }
|
|
|
|
|
+}
|