重拾 Java 高并发:两种异步模型(二)

127 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情

上一篇文章,我们一起学习了 Java 的第一种无返回值的异步模型 :重拾 Java 高并发:两种异步模型(一) 。今天我们继续来介绍 Java 并发编程中的第二种异步编程模型。

有返回值的异步模型

上篇文章,我们花了比较多的代码量手动实现了一个有返回值的异步回调逻辑,尽管这样能够获得异步返回结果,但是冗长的代码还是不够方便。在 Java 中,提供了可以直接返回异步结果的处理方案。最常用的就是使用 Future 接口或者其实现类 FutureTask 来接收任务的返回结果。下面我们用代码的方式来简要看看:

1.使用 Future 接口获取异步结果

使用Future接口往往配合线程池来获取异步执行结果:

import java.util.concurrent.*;

/**
 * @author zhongmingyi
 * @date 2023/2/5 11:01 下午
 */
public class FutureLearning {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<String> future = executor.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "异步任务执行结果";
            }
        });
        System.out.println(future.get());
        executor.shutdown();
    }
}
  • 首先初始化了一个线程池
  • 然后线程池中提交了一个任务,任务实现了一个Callable接口,它的 call 方法返回值就是这个任务执行的结果值
  • 线程池提交任务,返回 Future 接口对象
  • 调用 Future 对象的 get 方法,即可获取到异步任务的返回值

运行结果:

image.png

2.使用 FutureTask 类获取异步结果

FutureTask 类可以配合 Thread 类或线程池来使用。

结合Thread类的使用代码如下:

public class FutureTaskLearning1 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String> futureTask = new FutureTask<>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "异步任务执行结果";
            }
        });
        new Thread(futureTask).start();
        System.out.println(futureTask.get());
    }
}
  • 创建一个 FutureTask 对象
  • 创建一个 Thread,入参为 FutureTask 对象,启动线程
  • 调用 FutureTask 的 get 方法获取到异步任务的返回值

结合线程池的使用代码如下:

public class FutureTaskLearning2 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        FutureTask<String> futureTask = new FutureTask<>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "异步任务执行结果";
            }
        });
        executor.excute(futureTask);
        System.out.println(futureTask.get());
        executor.shutdown();
    }
}
  • 创建一个线程池
  • 创建一个 FutureTask 对象
  • 调用线程池的 excute 方法,入参为 FutureTask 对象
  • 调用 FutureTask 的 get 方法获取到异步任务的返回值