【异步编程学习笔记】JDK中的FutureTask和CompletableFuture详解(使用示例、源码)

本文详细介绍了FutureTask和CompletableFuture在Java异步编程中的应用,包括FutureTask的执行原理、使用实例,以及CompletableFuture的特性如通知等待、异步计算和结果转换,展示了如何利用它们进行任务调度和结果获取的灵活性。


FutureTask概述

FutureTask代表了一个可被取消的异步计算任务,该类实现了Future接口,比如提供了启动和取消任务、查询任务是否完成、获取计算结果的接口。 FutureTask任务的结果只有当任务完成后才能获取,并且只能通过get系列方法获取,当结果还没出来时,线程调用get系列方法会被阻塞。另外,一旦任务被执行完成,任务将不能重启,除非运行时使用了runAndReset方法。FutureTask中的任务可以是Callable类型,也可以是Runnable类型(因为FutureTask实现了Runnable接口),FutureTask类型的任务可以被提交到线程池执行。

使用实例

  public static String doSomethingA() {
   
   

        try {
   
   
            Thread.sleep(2000);
        } catch (InterruptedException e) {
   
   
            e.printStackTrace();
        }
        System.out.println("--- doSomethingA---");

        return "TaskAResult";
    }

    public static String doSomethingB() {
   
   
        try {
   
   
            Thread.sleep(2000);
        } catch (InterruptedException e) {
   
   
            e.printStackTrace();
        }
        System.out.println("--- doSomethingB---");
        return "TaskBResult";

    }
    public static void main(String args[]) throws ExecutionException, InterruptedException {
   
   
        long start = System.currentTimeMillis();

        // 1.创建future任务
        FutureTask<String> futureTask = new FutureTask<String>(() -> {
   
   
            String result = null;
            try {
   
   
                result = doSomethingA();

            } catch (Exception e) {
   
   
                e.printStackTrace();
            }
            return result;
        });

        // 2.开启异步单元执行任务A
        Thread thread = new Thread(futureTask, "threadA");
        thread.start();

        // 3.执行任务B
        String taskBResult = doSomethingB();

        // 4.同步等待线程A运行结束
        String taskAResult = futureTask.get();

        // 5.打印两个任务执行结果
        System.out.println(taskAResult + " " + taskBResult);
        System.out.println(System.currentTimeMillis() - start);

    }
    }

在这里插入图片描述
使用main线程执行任务doSomethingB,这时候任务doSomethingB和doSomethingA是并发运行的,等main函数运行doSomethingB完毕后,同步等待doSomethingA任务完成,然后代码5打印两个任务的执行结果。 ·如上可知使用FutureTask可以获取到异步任务的结果。当然我们也可以把FutureTask提交到线程池来执行,使用线程池运行方式的代码如下:

    // 0自定义线程池
    private final static int AVALIABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
    private final static ThreadPoolExecutor POOL_EXECUTOR = new ThreadPoolExecutor(AVALIABLE_PROCESSORS,
            AVALIABLE_PROCESSORS * 2, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(5),
            new ThreadPoolExecutor.CallerRunsPolicy());

    public static void main(String[] args) throws InterruptedException, ExecutionException {
   
   

        long start = System.currentTimeMillis();

        // 1.创建future任务
        FutureTask<String> futureTask = new FutureTask<String>(() -> {
   
   
            String result = null;
            try {
   
   
                result = doSomethingA();

            } catch (Exception e) {
   
   
                e.printStackTrace();
            }
            return result;
        });

        // 2.开启异步单元执行任务A
        POOL_EXECUTOR.execute(futureTask);

        // 3.执行任务B
        String taskBResult = doSomethingB();

        // 4.同步等待线程A运行结束
        String taskAResult = futureTask.get();
        // 5.打印两个任务执行结果
        System.out.println(taskAResult + " " + taskBResult);
        System.out.println(System.currentTimeMillis() - start);
    } 

下面代码与上面是等价的:

 public static void main(String[] args) throws InterruptedException, ExecutionException {
   
   

        long start = System.currentTimeMillis();

        // 1.开启异步单元执行任务A
        Future<String> futureTask =POOL_EXECUTOR.submit(() -> {
   
   
            String result = null;
            try {
   
   
                result = doSomethingA();

            } catch (Exception e) {
   
   
                e.printStackTrace();
            }
            return result;
        });

        // 2.执行任务B
        String taskBResult = doSomethingB();

        // 3.同步等待线程A运行结束
        String taskAResult = futureTask.get();
        // 4.打印两个任务执行结果
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值