可完成Future

  • 处理非阻塞调用的传统方法是使用事件处理器,程序员为任务完成之后出现的动作注册一个处理器。当然,如果下一个动作也是异步的,在它之后的下一个动作会在一个不同的事件处理器中。尽管程序员会认为,先做步骤1,然后是步骤2,再完成步骤3,但实际上程序逻辑会分散到不同的处理器中。如果必须增加错误处理,情况会更糟糕。假设步骤2是用户登录。可能需要重复这个步骤,因为用户输入凭据时可能会出错。要尝试在一组事件处理器中实现这样一个控制流,或者想要理解所实现的这样一组事件处理器,会很有难度。
  • Java SE 8的CompletableFuture类提供了一种候选方法。与事件处理器不同,可完成future可以组合
  • 例如,假设我们希望从一个Web页面抽取所有链接来建立一个网络爬虫。下面假设有这样一个方法
public void CompletableFuture<String> readPage(URL url)
  • Web页面可用时这会生成这个页面的文本。如果方法:
public static List<URL> getLinks(String page)
  • 生成一个HTML页面的URL,可以调度当页面可用时在调用这个方法:
CompletableFuture<String> contents = readPage(url);
CompletableFuture<List<URL>> links = contents.thenApply(Parser::getLinks);
  • thenApply方法不会阻塞。它会返回另一个future。第一个future完成时,其结果会提供给getLinks方法,这个方法的返回值就是最终的结果。
  • 有很多的方法组合可完成future。先来看处理单个future的方法
    为CompletableFuture对象添加一个动作
  • 调用
CompletableFuture<U> future.thenApply(f);
CompletableFuture<U> future.thenApplyAsync(f);
  • 会调用一个future,可用时会对future的结果应用f。第二个调用会在另一个线程中运行f。
  • thenCompose方法没有取函数T -> U,而是取函数T -> CompletableFuture<U>。这听上去相当抽象,不过实际上也很自然。考虑从一个给定URL读取一个Web页面的动作。不用提供方法:
public String blockingReadPage(URL url)
更巧妙的做法是让方法返回一个future
public CompletableFuture<String> readPage(URL url)
  • 现在,假设我们还有一个方法可以从用户输入得到URL,这可能从一个对话框得到,而在用户点击OK按钮之前不会得到答案。这也是将来的一个事件:
public CompletableFuture<URL> getURLInput(String prompt)
  • 这里我们有两个函数T -> CompletableFuture<U>U -> CompletableFuture<V>。显然,如果第二个函数在第一个函数完成时调用,它们就可以组合为一个函数 T -> CompletableFuture<V>。这正是thenCompose所做的。
  • 表中第3个方法强调了,CompletableFuture中抛出一个异常时,会捕获这个异常并在调用get方法时包装在一个受查异常ExecutionException中。不过,可能get永远也不会被调用。要处理异常,可以使用handle方法。调用指定的函数时要提供结果(如果没有则为null)和异常(如果没有则为null),这种情况下就要意义了。
  • 其余的方法结果都为void,通常用在处理管线的最后
  • 下面来看组合多个future方法
    组合多个组合对象
  • 前3个方法并行运行一个CompletableFuture<T>和一个CompletableFuture<U>动作,并组合结果。
  • 接下来3个方法并行运行两个CompletableFuture<T>动作。一旦其中一个完成,就传递它的结果,并忽略另一个结果。
  • 最后的静态allOfanyOf方法取一组可完成future(数目可变),并生成一个CompletableFuture<Void>,它会在所有这些future都完成时或者其中任意一个future完成时结束。不会传递任何结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值