Future 异步任务
定义Callable接口的实现
import java.util.concurrent.Callable; public class RealDataCallable implements Callable<String> { private String para; public RealDataCallable(String para) { this.para = para; } @Override public String call() throws Exception { StringBuffer sb = new StringBuffer(); for(int i=0; i<10; i++) { sb.append(para); Thread.sleep(1000); } return sb.toString(); } }
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; public class FutureDemo { public static void main(String[] args) throws InterruptedException, ExecutionException { FutureTask<String> future = new FutureTask<String>(new RealDataCallable("a")); ExecutorService es = Executors.newFixedThreadPool(1); //Future 是异步任务,提交请求之后,这里必然是立即返回的,因为程序不会阻塞 //接下来,不用关心数据是如何产生的。 //可以去做一些额外的事情,然后在需要的时候可以通过Future.get()得到实际的数据 es.submit(future); System.out.println("请求完毕"); //使用 sleep 代替其他业务逻辑的处理 Thread.sleep(1000); //获得call()方法的返回值,如果此时call()方法没有执行完成,则会等待 System.out.println("数据: " + future.get()); } }
通过CompletableFuture 提供的进一步封装,可以很容易实现Future模式那样的异步调用。
实例如下:
import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; public class AsyncTaskUseCompletableFuture { public static void main(String[] args) throws InterruptedException, ExecutionException { final CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> calc(50)); System.out.println(future.get()); } public static Integer calc(Integer para) { try { //模拟一个长时间的执行 Thread.sleep(1000); } catch (InterruptedException e) { } return para * para; } }
CompletableFuture 的组合
import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; public class ComposeCompletableFuture { public static void main(String[] args) throws InterruptedException, ExecutionException { //thenCompose 组合CompletableFuture // CompletableFuture<Void> fu = CompletableFuture.supplyAsync(() -> calc(50)) // .thenCompose((i) -> CompletableFuture.supplyAsync(() -> calc(i))) // .thenApply((str) -> """ + str + """ ) // .thenAccept(System.out::println); //thenCombine 组合CompletableFuture CompletableFuture<Integer> intFuture = CompletableFuture.supplyAsync(() -> calc(50)); CompletableFuture<Integer> intFuture2 = CompletableFuture.supplyAsync(() -> calc(25)); CompletableFuture<Integer> fu = intFuture.thenCombine(intFuture2, (i,j) -> (i + j)); System.out.println(fu.get()); } public static Integer calc(Integer para) { return para / 2; } }