美文网首页
Fork-Join框架

Fork-Join框架

作者: kindol | 来源:发表于2018-07-31 23:31 被阅读0次

    把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。

    F1

    工作窃取算法

    某个线程从其他队列里窃取任务来执行。使用的场景是一个大任务拆分成多个小任务,为了减少线程间的竞争,把这些子任务分别放到不同的队列中,并且每个队列都有单独的线程来执行队列里的任务,线程和队列一一对应。

    然而依然会出现一种情况:线程A先把队列里的工作搞定了,而B还有一些任务,A帮B做任务,但如果两个线程访问同一个队列,会产生竞争,所以A想了一个办法,从双端队列的尾部拿任务执行。而B线程永远是从双端队列的头部拿任务执行(任务是一个个独立的小任务)。

    F2.png
    • 优点:

    利用了线程进行并行计算,减少了线程间的竞争。

    • 缺点:
      1. 如果双端队列中只有一个任务时,线程间会存在竞争。
      2. 消耗了更多的系统资源,如会创建多个线程和多个双端队列。

    框架设计

    1. 分割任务

      使用fork类把大任务分割为小任务

    2. 执行任务合并结果

      分割的子任务分别放在双端队列里,启动线程从双端队列获取任务并执行。执行结果放在同一的一个队列,启动一个线程从队列里拿数据,然后合并

    使用2个类完成以上事务:

    1. ForkJoinTask:提供在任务中执行fork和join操作的机制。一般情况下,我们并不需要直接继承ForkJoinTask类,只需要继承它的子类,它的子类有两个:
    • RecursiveAction:用于没有返回结果的任务。
    • RecursiveTask:用于有返回结果的任务。
    1. ForkJoinPool:任务ForkJoinTask需要通过ForkJoinPool来执行。

    参见代码CountTask

    异常处理

    使用isCompletedAbnormally()检查任务是否已经抛出异常或者被取消,并且可以通过ForkJoinTask的getException()获取异常

    实现原理

    • fork

      调用pushTask方法异步执行任务,然后返回,pushTask方法将当前任务存放在ForkJoinTask数组队列里,然后再调用ForkJoinPool的signalWork()唤醒或创建一个工作线程来执行任务

    • join

      主要作用是阻塞当前线程并等待获取结果,当中会调用doJoin()判断当前任务的状态

    相关文章

      网友评论

          本文标题:Fork-Join框架

          本文链接:https://www.haomeiwen.com/subject/svikvftx.html