看码看图👇👇🏿👇🏻:
CompletableFuture cf = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello result";
});
System.out.println(cf.thenAccept(System.out::println));
System.out.println("阻塞了吗");
方法是异步执行了,但是为啥没有返回值呢?哈哈哈
原因是supplyAsync()使用的默认的ForkJoinPool来创建线程,这样创建的线程都是守护线程。
当唯一运行的线程都是守护线程时,Java 虚拟机退出,该线程停止执行,所以才没有输出结果。
/**
* 返回一个新的 CompletableFuture,它由在ForkJoinPool.commonPool()运行的任务异步完成,其值是通过调用给定的供应商获得的。
*/
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
return asyncSupplyStage(asyncPool, supplier);
}
private static final Executor asyncPool = useCommonPool ?
ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();
public static ForkJoinPool commonPool() {
// assert common != null : "static init error";
return common;
}
static final ForkJoinPool common;
public ForkJoinPool() {
this(Math.min(MAX_CAP, Runtime.getRuntime().availableProcessors()),
defaultForkJoinWorkerThreadFactory, null, false);
}
public static final ForkJoinWorkerThreadFactory
defaultForkJoinWorkerThreadFactory;
public static interface ForkJoinWorkerThreadFactory {
public ForkJoinWorkerThread newThread(ForkJoinPool pool);
}
static final class DefaultForkJoinWorkerThreadFactory
implements ForkJoinWorkerThreadFactory {
public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
return new ForkJoinWorkerThread(pool, null);
}
}
ForkJoinWorkerThread(ForkJoinPool pool, Object unused) {
super("aForkJoinWorkerThread");
U.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, INNOCUOUS_ACC);
this.pool = pool;
this.workQueue = pool.registerWorker(this);
}
final WorkQueue registerWorker(ForkJoinWorkerThread wt) {
UncaughtExceptionHandler handler;
wt.setDaemon(true); // 配置线程为守护线程
if ((handler = ueh) != null)
wt.setUncaughtExceptionHandler(handler);
WorkQueue w = new WorkQueue(this, wt);
int i = 0;
int mode = config & MODE_MASK;
int rs = lockRunState();
try {...} finally {...}
wt.setName(workerNamePrefix.concat(Integer.toString(i >>> 1)));
return w;
}
知道问题了,改一下吧,艹。自己创建一个线程池vans
CompletableFuture cf = CompletableFuture.supplyAsync(() -> {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello result";
}, ThreadPoolUtil.executor).thenAcceptAsync(System.out::println);
System.out.println("阻塞了吗");