Java8-CompletableFuture的使用

文章介绍了Future接口在Java并发编程中的作用,随后转向了Java8引入的CompletableFuture,展示了如何使用CompletableFuture简化异步任务的处理,如执行异步操作、组合任务和处理结果。通过例子展示了如何使用CompletableFuture替代Future来同时获取用户和勋章信息。
摘要由CSDN通过智能技术生成

Future接口

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 实例、以及对它们进行组合和操作。一些常用的方法包括:

  • supplyAsync():用于执行一个异步任务并返回结果。
  • thenApply():用于在一个 CompletableFuture 上执行一个操作,并返回一个新的 CompletableFuture 对象。
  • thenCompose():用于将两个 CompletableFuture 对象进行组合,将一个 CompletableFuture 的结果作为参数传递给另一个 CompletableFuture。
  • thenCombine():用于将两个 CompletableFuture 对象进行组合,并将它们的结果进行合并。
  • whenComplete():用于注册一个回调方法,在 CompletableFuture 执行完成时执行该回调方法。
  • handle():用于注册一个回调方法,可以对成功结果和异常进行处理。

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();
    }
}

修改Future 模拟同时获取用户和勋章

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 的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值