Java Language
Programmation parallèle avec framework Fork / Join
Recherche…
Tasks / Join Tasks in Java
Le framework fork / join en Java est idéal pour un problème qui peut être divisé en parties plus petites et résolu en parallèle. Les étapes fondamentales d'un problème fork / join sont les suivantes:
- Diviser le problème en plusieurs morceaux
- Résoudre chacune des pièces en parallèle
- Combinez chacune des sous-solutions en une solution globale
Une ForkJoinTask est l'interface qui définit un tel problème. On s'attend généralement à ce que vous sous-classiez l'une de ses implémentations abstraites (généralement la RecursiveTask ) plutôt que d'implémenter l'interface directement.
Dans cet exemple, nous allons additionner une collection d’entiers, en divisant jusqu’à ce que nous atteignions des tailles de lots ne dépassant pas dix.
import java.util.List;
import java.util.concurrent.RecursiveTask;
public class SummingTask extends RecursiveTask<Integer> {
private static final int MAX_BATCH_SIZE = 10;
private final List<Integer> numbers;
private final int minInclusive, maxExclusive;
public SummingTask(List<Integer> numbers) {
this(numbers, 0, numbers.size());
}
// This constructor is only used internally as part of the dividing process
private SummingTask(List<Integer> numbers, int minInclusive, int maxExclusive) {
this.numbers = numbers;
this.minInclusive = minInclusive;
this.maxExclusive = maxExclusive;
}
@Override
public Integer compute() {
if (maxExclusive - minInclusive > MAX_BATCH_SIZE) {
// This is too big for a single batch, so we shall divide into two tasks
int mid = (minInclusive + maxExclusive) / 2;
SummingTask leftTask = new SummingTask(numbers, minInclusive, mid);
SummingTask rightTask = new SummingTask(numbers, mid, maxExclusive);
// Submit the left hand task as a new task to the same ForkJoinPool
leftTask.fork();
// Run the right hand task on the same thread and get the result
int rightResult = rightTask.compute();
// Wait for the left hand task to complete and get its result
int leftResult = leftTask.join();
// And combine the result
return leftResult + rightResult;
} else {
// This is fine for a single batch, so we will run it here and now
int sum = 0;
for (int i = minInclusive; i < maxExclusive; i++) {
sum += numbers.get(i);
}
return sum;
}
}
}
Une instance de cette tâche peut maintenant être transmise à une instance de ForkJoinPool .
// Because I am not specifying the number of threads
// it will create a thread for each available processor
ForkJoinPool pool = new ForkJoinPool();
// Submit the task to the pool, and get what is effectively the Future
ForkJoinTask<Integer> task = pool.submit(new SummingTask(numbers));
// Wait for the result
int result = task.join();
Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow