9.10 练习

本章只有一个练习:使用CompletableFuture重构代码。先以例9-18中所示的BlockingArtistAnalyzer类开始,该类从两个艺术家的名字中找出成员数更多的那个,如果第一个艺术家的成员多,返回true,否则返回false。该类被注入一个artistLookupService,因为查找Artist的过程可能会耗费一定时间。由于BlockingArtistAnalyzer类要依序调用两次查找服务,分析就会变慢,练习的目标就是加速这一过程。

例9-18 BlockingArtistAnalyzer告诉用户哪位艺术家的成员更多

  1. public class BlockingArtistAnalyzer {
  2. private final Function<String, Artist> artistLookupService;
  3. public BlockingArtistAnalyzer(Function<String, Artist> artistLookupService) {
  4. this.artistLookupService = artistLookupService;
  5. }
  6. public boolean isLargerGroup(String artistName, String otherArtistName) {
  7. return getNumberOfMembers(artistName) > getNumberOfMembers(otherArtistName);
  8. }
  9. private long getNumberOfMembers(String artistName) {
  10. return artistLookupService.apply(artistName)
  11. .getMembers()
  12. .count();
  13. }
  14. }

练习分成两部分,第一部分是使用一个回调接口重构阻塞代码。在这里,我们将使用ConsumerConsumer是JVM自带的一个函数接口,接受一个参数,返回空。读者的任务就是修改BlockingArtistAnalyzer,实现ArtistAnalyzer(如例9-19所示)。

例9-19 需要实现的ArtistAnalyzer接口

  1. public interface ArtistAnalyzer {
  2. public void isLargerGroup(String artistName,
  3. String otherArtistName,
  4. Consumer<Boolean> handler);
  5. }

现在我们有了一个符合回调模型的API,就不需要同时执行两次阻塞式的查找了。使用CompletableFuture类重构isLargerGroup方法,让其可以并行执行。