(四)深入并发编程之异步回调

深入并发编程之异步回调


前言

通过上一节的学习,我们明白了什么是任务。但是我为什么没有去分析线程池的submit方法呢?因为在实际工作中我们并不用到它。


线程的异步

    public static void main(String[] args){
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                1,  // 核心线程数
                2, // 最大线程数
                60, // 线程存活时间
                TimeUnit.SECONDS, // 存活时间单位
                new LinkedBlockingQueue<>(),// 阻塞队列
                Executors.defaultThreadFactory(),// 线程工厂
                new ThreadPoolExecutor.AbortPolicy());// 拒绝策略

        Future<String> submit = threadPoolExecutor.submit(() -> {
            return "hello future";
        });

    }

1.1 Future是什么?

通过上述代码,我们可以看到,通过线程池的submit方法会返回一个Future对象,我们点进去发现:

在这里插入图片描述

Future是一个接口,它里面定义了一些通用方法,例如任务是否完成,获取任务结果等。

再看看submit里面到底是什么:

在这里插入图片描述

可以看到,底层是 new 了一个 FutureTask对象。

1.2. FutureTask

那么我们怎么能获取到异步执行结果呢?

在这里插入图片描述

第一种是调用 get 方法。这会阻塞主线程,很明显这跟单线程没啥区别

在这里插入图片描述

第二种是调用 isDone方法循环获取结果。这样虽然不影响主线程执行,但是如果子任务耗时,会导致CPU空转,影响性能。而且这样某种意义上来说还是单线程,万一主线程需要等到子任务结果才能继续执行呢?

1.3. CompletableFuture

在这里插入图片描述

这是Java8的一个新类,同样实现了Future接口,除此之外还实现了一个新接口,可以理解为步骤。(即如果下一个子任务需要上一个子任务的执行结果,可以直接串联执行。)

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                1,  // 核心线程数
                2, // 最大线程数
                60, // 线程存活时间
                TimeUnit.SECONDS, // 存活时间单位
                new LinkedBlockingQueue<>(),// 阻塞队列
                Executors.defaultThreadFactory(),// 线程工厂
                new ThreadPoolExecutor.AbortPolicy());// 拒绝策略

        CompletableFuture.supplyAsync(() -> {
                    try {
                        System.out.println("进入第一个子任务");
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    return "hello CompletableFuture";
                }, threadPoolExecutor)
                .thenApply(s -> {
                    System.out.println("进入第二个子任务");
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    return s;
                }).thenAccept(
                   System.out::println
                );

        System.out.println("主线程执行11");
        System.out.println("主线程执行22");
        System.out.println("主线程执行33");
    }

在这里插入图片描述

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值