异步编程一:Future 局限性

79 阅读1分钟

从本质上说,Future表示一个异步计算的结果。它提供了isDone()来检测计算是否已经完成,并且在计算结束后,可以通过get()方法来获取计算结果。在异步计算中,Future确实是个非常优秀的接口。但是,它的本身也确实存在着许多限制:

  • 并发执行多任务:Future只提供了get()方法来获取结果,并且是阻塞的。所以,除了等待你别无他法;当 for 循环批量获取 Future 的结果时容易 block,因此get 方法调用时应使用 timeout 限制。
  • 无法对多个任务进行链式调用:如果你希望在计算任务完成后执行特定动作,比如发邮件,但Future却没有提供这样的能力;
  • 无法组合多个任务:如果你运行了10个任务,并期望在它们全部执行结束后执行特定动作,那么在Future中这是无能为力的;
  • 没有异常处理:Future接口中没有关于异常处理的方法;

写一个future demo, 这个demo 需要做四件事:

  • step1: 读取敏感词汇 => thread1
  • step2: 读取文本 => thread2
  • step3: 替换操作 => thread3
  • step4: 打印替换后的文本
public class FutureDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(5);

        // step1: 读取敏感词汇 => thread1
        Future<List<String>> filterWordFuture = executor.submit(() -> {
            return FileUtil.getLines("filter_words.txt");
        });

        // step2: 读取文本 => thread2
        Future<String> wordFuture = executor.submit(() -> {
            return FileUtil.getContent("text.txt");
        });

        // step3: 替换操作 => thread3
        Future<String> replaceFuture = executor.submit(() -> {
            List<String> filterWords = filterWordFuture.get();
            String words = wordFuture.get();

            for (String filterWord : filterWords) {
                words = words.replace(filterWord, "**");
            }

            return words;
        });

        // step4: 打印替换后的文本
        String replace = replaceFuture.get();
        System.out.println(replace);

        executor.shutdown();
    }
}