2010-08-19 1 views

ответ

4
+0

Я пытался объяснить это в глубине здесь: [Java: с помощью вилки/Join Framework для параллельного разрешения разделяй-и-властвуй проблемы] (http://www.davismol.net/2016/ 01/24/java-using-the-forkjoin-framework-for-the-parallel-resolution-of-divide-and-ququer-problems /) –

2

Скажем, у вас есть коллекция вещей, которые должны быть обработаны. У вас есть несколько потоков, которые могут захватывать подмножества этой коллекции и обрабатывать их. Они все делают это одновременно (часть вилки), а затем ждут последнего, чтобы закончить (часть соединения), прежде чем вернуться.

+0

С учетом того, что текущий родительский_stops выполняет_ до тех пор, пока все параллельные рабочие не закончатся, и _then_ резюме. Я знаю, что это было присуще вашему описанию, но я думаю, что стоит быть очень явным, потому что это все, что действительно отличает его от любого другого явного параллелизма. – Gian

+0

Ну, это не fork нагрузка операций, выполнить их все, а затем присоединиться. Это подход с разницей и покорением. –

8

Fork Join - это новая структура, которая имеет более простой в использовании API для алгоритма параллельного, деления и завоевания.

Скажите, что у вас долго работающая задача, которая для этого экземпляра имеет сложный алгоритм. Вы хотели бы развить большие задачи и теперь работать над этими двумя задачами. Теперь давайте скажем, что эти две задачи все еще слишком велики, вы должны разбить каждую на две задачи (на данный момент их четыре).

Вы продолжаете это до тех пор, пока каждая задача не будет иметь приемлемый размер и вызовет алгоритм. Важно знать, что вызов каждой задачи выполняется параллельно. Когда задача завершена, она объединяется с другой задачей, с которой она была разветвлена, и консолидировать результаты.

Это будет продолжаться до тех пор, пока все задачи не будут объединены, и одна задача будет возвращена.

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)); 
    } 

} 
1

Пусть я просто поставил свои два цента, чтобы сделать базовое представление о вилке/объединении просто.

What is Fork/Join? 

The fork/join framework is an implementation of the ExecutorService interface 
that helps you take advantage of multiple processors. It is designed for work 
that can be broken into smaller pieces recursively. The goal is to use all the 
available processing power to enhance the performance of your application. 
  • Эта система очень полезна для моделирования разделяй и властвуй проблем. Этот подход подходит для задач, которые можно разделить на рекурсивно и вычислять в меньших масштабах; вычисленные результаты равны , затем объединены.
  • Фреймворк представляет собой реализацию интерфейса ExecutorService и предоставляет простую в использовании параллельную платформу для использования нескольких процессоров .

Срок полезной для этой структуры

  • Разветвление: Разделение задачи на более мелкие задачи является разветвление.
  • Присоединение: Объединение результатов от небольших задач является присоединение

Как и при любой реализации ExecutorService, вилка/нарисуйте рамки распределяют задачи на рабочие потоки в пуле потоков. Рамка fork/join отличается тем, что использует алгоритм обработки рабочего времени . Рабочие потоки, которые не работают, могут украсть задачи из других потоков, которые все еще заняты.

развилки/Join алгоритм разработан следующим образом:

  • сплит задачи
  • вилы задачи
  • присоединиться задачи
  • составляют результаты
doRecursiveTask(input){ 
    if(task is small enough to handled by a thread){ 
     compute the small task; 
     if there is result to return, then do so 
    }else{ 
     divide the task i.e, fork() into two parts 
     call compute on first task, join on second task, combine both results and return 
    } 
} 

Что такое алгоритм обработки работы?

Каждый рабочий поток в Fork/Join рамки имеет очередь работы, которая реализуется с использованием Deque. Каждый раз, когда новая задача (или подзадача) создается , она помещается в голову собственной очереди. Когда задача завершает задачу и выполняет соединение с другой задачей, которая не завершена , она работает умнее. Поток выдает новую задачу из заголовка своей очереди и начинает выполнение, а не спящий (в порядке , чтобы дождаться завершения другой задачи). На самом деле, если очередь потока пуста, то поток выдает задачу из хвоста очереди , принадлежащей другому потоку. Это не что иное, как кража работы . More detail is here