当前位置:嗨网首页>书籍在线阅读

11-异步地运行任务

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

5.4 异步地运行任务

ForkJoinPool 内执行 ForkJoinTask 时,我们可以选择同步方式或异步方式。采用同步方式时,方法会等到提交的任务执行完成后才返回;采用异步方式时,方法将任务提交给执行器后会立刻返回,从而任务可以继续执行。

你需要意识到这两种方式之间存在巨大差异。当使用同步方式时,调度任务会暂停等待池中的任务执行完毕。这种方式允许 ForkJoinPool 类使用工作量测算法来分配一个新的任务给当前休眠的工作线程。相反,如果使用异步方式,则任务会继续执行, ForkJoinPool 类不会使用工作量测算法来提升应用性能。在本例中,只有在调用 join() 或是 get() 方法来等待任务结束时, ForkJoinPool 类才会使用该算法。

除了 RecursiveActionRecursiveTask 类,Java 8新加入了基于 Counted Completer 类的 ForkJoinTask 类。使用这类任务时,你可以加入一个完成方法。当任务启动且没有处理其中的子任务时,会调用该方法。该机制基于 ForkJoinTask 类中的 onCompletion() 方法和一个处理任务的计数器来实现。

这个计数器的默认值为 0 ,在需要时它可以自动自增。一般来说,在启动子任务时,计数值会自动增加 1 。最后,当一个任务执行完成时,你可以试着结束任务,并持续调用 onCompletion() 方法。如果处理中的任务计数值大于 0 ,则该计数值会自行减少 1 。如果计数为 0 ,则 onCompletion() 方法会执行且父任务会尝试结束。在本节中,读者将通过实现一个在文件夹和子文件夹下搜索文件的功能,来了解到如何使用 ForkJoinPool 类和 CountedCompleter 类提供的异步方式来管理任务。 CountedCompleter 类将处理文件夹内容,对文件夹内的每个子文件夹都将异步提交一个新的任务到 ForkJoinPool 类。而对文件夹中的每个文件,任务将检查文件的扩展名并添加到执行结果列表中。当一个任务执行完成时,它将在结果任务中插入全部子任务的结果列表。