Future接口是Java并发编程中的一个接口,它表示一个可能还没有完成的异步操作的结果。Future接口的主要作用是提供一种机制,允许调用者在某个异步操作完成后取得其结果
@Data
@AllArgsConstructor
public class MedalInfo {
public String id;
public String name;
}
@Data
@AllArgsConstructor
public class UserInfo {
public String id;
public String name;
public int age;
}
/**
* 勋章服务
*/
public class MedalService {
public MedalInfo getMedalInfo(long userId){
try {
Thread.sleep(500); //模拟调用耗时
} catch (InterruptedException e) {
e.printStackTrace();
}
return new MedalInfo("666", "守护勋章");
}
}
/**
* 用户服务
*/
public class UserInfoService {
public UserInfo getUserInfo(Long userId){
try {
Thread.sleep(300);//模拟调用耗时
} catch (InterruptedException e) {
e.printStackTrace();
}
return new UserInfo("666", "捡田螺的小男孩", 27); //一般是查数据库,或者远程调用返回的
}
}
用Future 模拟同时获取 用户和勋章
public class FutureTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
UserInfoService userInfoService = new UserInfoService();
MedalService medalService = new MedalService();
long userId = 666L;
long startTime = System.currentTimeMillis();
//调用用户服务获取用户基本信息
FutureTask<UserInfo> userInfoFutureTask = new FutureTask<>(new Callable<UserInfo>() {
@Override
public UserInfo call() throws Exception {
return userInfoService.getUserInfo(userId);
}
});
executorService.submit(userInfoFutureTask);
Thread.sleep(300); //模拟主线程其它操作耗时
FutureTask<MedalInfo> medalInfoFutureTask = new FutureTask<>(new Callable<MedalInfo>() {
@Override
public MedalInfo call() throws Exception {
return medalService.getMedalInfo(userId);
}
});
executorService.submit(medalInfoFutureTask);
UserInfo userInfo = userInfoFutureTask.get();//获取个人信息结果
MedalInfo medalInfo = medalInfoFutureTask.get();//获取勋章信息结果
executorService.shutdown(); // 关闭ExecutorService
System.out.println("总共用时" + (System.currentTimeMillis() - startTime) + "ms");
}
}
CompletableFuture 是 Java 8 引入的一个类,用于处理异步编程和并发操作。它提供了一种简洁、强大和灵活的方式来处理异步任务。
CompletableFuture 可以看作是一个可以执行异步操作的容器,可以将多个异步任务组合在一起,以便在一个或多个任务完成时执行特定操作。
CompletableFuture 类提供了一系列的方法,用于创建 CompletableFuture 实例、以及对它们进行组合和操作。一些常用的方法包括:
CompletableFuture 的一个重要特点是它支持链式调用,可以通过不断地调用上述方法组合多个 CompletableFuture 对象,形成一条执行流水线。
通过使用 CompletableFuture,可以更简洁地处理异步编程和并发操作,提高代码的可读性和可维护性。同时,CompletableFuture 还提供了一些其他高级特性,如超时机制和异常处理,使得处理异步任务更加灵活和强大。
public class Test2 {
public static void asyncCallback() throws ExecutionException, InterruptedException {
CompletableFuture<Integer> task = CompletableFuture.supplyAsync(new Supplier<String>() {
@Override
public String get() {
System.out.println(Thread.currentThread().getName() + "supplyAsync");
return "123";
}
}).thenApply(number -> {
System.out.println(Thread.currentThread().getName() + "thenApply1");
return Integer.parseInt(number);
}).thenApply(number -> {
System.out.println(Thread.currentThread().getName() + "thenApply2");
return number * 2;
});
task.thenRun(()->{
System.out.println(Thread.currentThread().getName()+"thenRun: 收尾任务");
});
System.out.println(Thread.currentThread().getName() + " => " + task.get());
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
asyncCallback();
}
}
public class FutureTest1 {
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
UserInfoService userInfoService = new UserInfoService();
MedalService medalService = new MedalService();
long userId =666L;
long startTime = System.currentTimeMillis();
//调用用户服务获取用户基本信息
CompletableFuture<UserInfo> completableUserInfoFuture = CompletableFuture.supplyAsync(() -> userInfoService.getUserInfo(userId));
Thread.sleep(300); //模拟主线程其它操作耗时
CompletableFuture<MedalInfo> completableMedalInfoFuture = CompletableFuture.supplyAsync(() -> medalService.getMedalInfo(userId));
UserInfo userInfo = completableUserInfoFuture.get(2, TimeUnit.SECONDS);//获取个人信息结果
MedalInfo medalInfo = completableMedalInfoFuture.get();//获取勋章信息结果
System.out.println("总共用时" + (System.currentTimeMillis() - startTime) + "ms");
}
}
代码上简洁很多,同样也能实现Future 的功能。