11

有人能解释一下 Fork/Join 是什么吗?

4

4 回答 4

8

Fork Join 是一个新的框架,它具有更易于使用的 API,用于并行、分而治之的算法。

假设您有一个长时间运行的任务,在这种情况下,它有一个复杂的算法。您可能希望分叉大型任务,然后处理这两个任务。现在假设这两个任务仍然太大,您可以将每个任务分成两个任务(此时有四个)。

您将继续此操作,直到每个任务都处于可接受的大小并调用算法。重要的是要知道每个任务的调用是并行完成的。当任务完成时,它会与它被分叉的另一个任务结合起来并合并结果。

这将一直持续到所有任务都已加入并返回一项任务。

于 2010-08-19T20:02:34.213 回答
3

除了已经说过的之外,fork/join 还利用了工作窃取——没有事情可做的线程可以从其他仍在忙碌的线程中窃取任务。这是一个可以帮助您了解如何使用 FJ 的示例:

public class SumCounter extends RecursiveTask<Long> { 

  private final Node node; 

  public SumCounter(Node node) { 
    this.node = node; 
  } 

  @Override
  protected Long compute() { 
    long sum = node.getValue();
    List<ValueSumCounter> subTasks = new LinkedList<>(); 

    for(Node child : node.getChildren()) { 
      SumCounter task = new SumCounter(child); 
      task.fork(); // run asynchronously
      subTasks.add(task); 
    }

    for(SumCounter task : subTasks) { 
      sum += task.join(); // wait for the result 
    } 

    return sum;
  }

  public static void main(String[] args) { 
    Node root = getRootNode(); 
    new ForkJoinPool().invoke(new SumCounter(root)); 
  }

}
于 2012-02-08T15:43:33.127 回答
2

假设您有一组需要处理的东西。您有许多线程可以获取该集合的子集并对其进行处理。他们都同时执行此操作(fork 部分),然后等待最后一个完成(join 部分),然后再返回。

于 2010-08-19T17:53:48.360 回答
1

我将回答什么是 Fork Join 并行性。这是在许多系统中广泛用于实现并发的并行设计模式之一。我将用一个例子来解释这个设计模式。

例如,假设我们有执行一系列任务的程序:

A -> B -> C -> D. 这里 A,B,C,D 是任务。

  • A 需要 8 秒
  • B 需要 4 秒
  • C 需要 6 秒
  • D 需要 7 秒

所以这个程序执行总共需要 8+4+6+7 = 25 秒。

现在您发现任务 A、B、C 是独立的,而 D 取决于 A、B、C 任务的结果。现在你可能会有一种感觉,我们可以同时开始执行 B,而不是等待 A 完成。任务 C 也一样,可以与 A 和 B 同时启动任务。您可以做的是:您可以通过主线程调用 3 个新线程并为其分配 A、B、C 任务并等待结果,然后再开始执行任务D. 如果您的机器有多个内核,那么这些线程可以并行运行。

现在程序的执行时间是:

max(time_taken_A,_B,_C) + time_taken_D + threading_overhead_time

这几乎等于 = 8 + 7 + k = 15 + k;

在 fork join 并行性中,只有当这些任务是独立的时,我们才能使用新线程卸载任务。否则,我们将面临竞争条件。如果您有一个程序,其中一个任务正在等待另一个任务执行,但这不依赖于它的结果,那么您可以使用 fork join 并行性使用新线程卸载这两个任务,您可以获得性能提升。但总是想着头顶的穿线。如果您的任务非常轻量级,那么使用这些并行模式将降低您的性能,因为线程创建、上下文切换开销。

于 2019-10-10T18:18:35.913 回答