FutureTask
public static void main(String[] args) throws Exception {
FutureTask futureTask = new FutureTask<>(() -> {
System.out.println(Thread.currentThread().getName() + " come in");
try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }
return 1024;
});
new Thread(futureTask).start();
/* System.out.println(futureTask.get()); // get()会阻塞直到线程完成才会继续执行
System.out.println(futureTask.get(2L, TimeUnit.SECONDS)); // 带过期时间的阻塞*/
//不要阻塞,尽量用轮询替代
while(true){
if(futureTask.isDone()){
System.out.println("----result: "+futureTask.get());
break;
}else{
System.out.println("还在计算中,别催,越催越慢,再催熄火");
}
}
}
get()和join()都能获取返回结果,也都会阻塞
get()阻塞,一旦调用get(),不管计算是否完成都会导致阻塞
isDone()轮询,如果想要异步获取结果,通常都会以轮询的方式去获取结果,尽量不要阻塞。轮询的方式会额外消耗的CPU资源。
如何避免阻塞了?引入了CompletableFuture
CompletionStage:代表异步计算过程中的某一个阶段,一个阶段完成以后可能会触发另一个阶段
CompletableFuture:在Java8中CompletableFuture提供了非常强大的future的扩展功能,可以帮助我们简化异步编程的复杂性,并且提供了函数式编程的能力,可以通过回调的方式处理计算结果,也提供了转换和组合CompletableFuture的方法。
它有四个核心的静态方法来创建一个异步操作
无返回值
public static CompletableFuture runAsync(Runnable runnable);
public static CompletableFuture runAsync(Runnable runnable, Executor executor);
有返回值
public static CompletableFuture supplyAsync(Supplier supplier);
public static CompletableFuture supplyAsync(Supplier supplier, Executor executor)
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 20, 1, TimeUnit.MINUTES,
new LinkedBlockingQueue<>(50), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
CompletableFuture exceptionally = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().getName() + " come in");
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 2;
}, executor).whenComplete((v, e) -> {
if (e == null) {
System.out.println("result = " + v);
}
}).exceptionally(e -> {
e.printStackTrace();
return null;
});
// get()和join()都能获取返回结果,也都会阻塞
// exceptionally.get(); // 会抛出异常ExecutionException, InterruptedException
// exceptionally.join(); // 和不会抛出异常,推荐使用join()获取结果
// CompletableFuture要使用自定义创建的线程池,如果使用默认的线程池,则主线程结束后默认的线程池就会销毁,异步线程的代码就不会执行
executor.shutdown();
System.out.println("main thread over");
}
进微信群和大佬面对面学习交流