Kap. 12: Fork-Join

main
Sandro Leuchter 2024-12-15 17:28:07 +01:00
parent 3bf39b1f4c
commit 5aa83f1b3d
19 changed files with 792 additions and 0 deletions

View File

@ -0,0 +1,7 @@
# Laboraufgabe "in-situ Filterung als divide and conquer"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-01-ForkJoinArrayFilter.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-Solutions.html#laboraufgabe-in-situ-filterung-als-divide-and-conquer)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/12-forkjoin.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/12-forkjoin.html)

View File

@ -0,0 +1,19 @@
# Justfile (https://just.systems/) for starting Maven standard targets
default:
just exec pp.FilterTask ""
exec class args: compile
mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
# exec class args:
# java -cp target/app.jar {{class}} {{args}}
clean:
mvn clean
compile:
mvn compile
test: compile
mvn test
javadoc:
mvn javadoc:javadoc
package:
mvn package

View File

@ -0,0 +1,72 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pp</groupId>
<artifactId>pp.12.01-ForkJoinArrayFilter</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.FilterTask</exec.mainClass>
<maven.compiler.release>10</maven.compiler.release>
<lombok.version>edge-SNAPSHOT</lombok.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency><!-- für Unit-Tests -->
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency><!-- für Lombok -->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency><!-- für net.jcip Annotationen -->
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>clean compile exec:java</defaultGoal>
<plugins>
<plugin><!-- für Unit-Tests [mvn test] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin><!-- [mvn compile] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin><!-- [mvn exec:java] -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin><!-- [mvn javadoc:javadoc] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<show>private</show>
<locale>en_US</locale>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,57 @@
package pp;
import java.util.ArrayList;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.ForkJoinPool;
@SuppressWarnings("serial")
public class FilterTask extends RecursiveAction {
private static final int ARRAY_LEN = 16;
private static final int SLICE_LEN = 4;
private static final int MAX = 10;
private static int instanceCounter = 0;
private final ArrayList<Integer> array;
private final int start;
private final int end;
FilterTask(ArrayList<Integer> array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
synchronized(FilterTask.class) {
FilterTask.instanceCounter++;
}
}
@Override
protected void compute() {
// Fallunterscheidung einführen, die prüft, ob weiter rekursiv halbiert
// werden muss oder ob nun der Rekursionsanker erreicht ist
// Rekursionsanker: über Array-Elemente mit einer for-Schleife iterieren
// und Filter-Aktion anwenden (muss noch implementiert werden)
// Array in zwei Hälften aufteilen und beide Hälften rekursiv behandeln:
var mid = this.start + ((this.end - this.start) / 2);
var left = new FilterTask(this.array, this.start, mid);
var right = new FilterTask(this.array, mid, this.end);
left.fork();
right.fork();
right.join();
left.join();
}
public static void main(String... args) {
// Array initialisieren
// initialen FilterTask erzeugen und
// FilterTask im *Common Thread Pool* starten:
// ForkJoinPool.commonPool().invoke(...);
// auf das Ende warten
// gefiltertes Array ausgeben
}
}

View File

@ -0,0 +1,7 @@
# Laboraufgabe "in-situ Filterung als divide and conquer"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-01-ForkJoinArrayFilter.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-Solutions.html#laboraufgabe-in-situ-filterung-als-divide-and-conquer)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/12-forkjoin.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/12-forkjoin.html)

View File

@ -0,0 +1,19 @@
# Justfile (https://just.systems/) for starting Maven standard targets
default:
just exec pp.FilterTask ""
exec class args: compile
mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
# exec class args:
# java -cp target/app.jar {{class}} {{args}}
clean:
mvn clean
compile:
mvn compile
test: compile
mvn test
javadoc:
mvn javadoc:javadoc
package:
mvn package

View File

@ -0,0 +1,72 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pp</groupId>
<artifactId>pp.12.01-ForkJoinArrayFilter_solution</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.FilterTask</exec.mainClass>
<maven.compiler.release>10</maven.compiler.release>
<lombok.version>edge-SNAPSHOT</lombok.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency><!-- für Unit-Tests -->
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency><!-- für Lombok -->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency><!-- für net.jcip Annotationen -->
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>clean compile exec:java</defaultGoal>
<plugins>
<plugin><!-- für Unit-Tests [mvn test] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin><!-- [mvn compile] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin><!-- [mvn exec:java] -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin><!-- [mvn javadoc:javadoc] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<show>private</show>
<locale>en_US</locale>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,62 @@
package pp;
import java.util.ArrayList;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.ForkJoinPool;
@SuppressWarnings("serial")
public class FilterTask extends RecursiveAction {
private static final int ARRAY_LEN = 16;
private static final int SLICE_LEN = 4;
private static final int MAX = 10;
private static int instanceCounter = 0;
private final ArrayList<Integer> array;
private final int start;
private final int end;
FilterTask(ArrayList<Integer> array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
synchronized(FilterTask.class) {
FilterTask.instanceCounter++;
}
}
@Override
protected void compute() {
if ((this.end - this.start) <= SLICE_LEN) {
for (var i = this.start; i < this.end; i++) {
if (this.array.get(i) > MAX) {
this.array.set(i, MAX);
}
}
} else {
var mid = this.start + ((this.end - this.start) / 2);
var left = new FilterTask(this.array, this.start, mid);
var right = new FilterTask(this.array, mid, this.end);
left.fork();
right.fork();
right.join();
left.join();
}
}
public static void main(String... args) {
var array = new ArrayList<Integer>();
for (var i = 0; i < ARRAY_LEN; i++) {
array.add(i + 1);
}
var task = new FilterTask(array, 0, array.size());
ForkJoinPool.commonPool().invoke(task);
for (var number : array) {
System.out.print(number + " ");
}
System.out.println("\nAnzahl der verwendeten Instanzen von FilterTask: "
+ FilterTask.instanceCounter);
}
}

View File

@ -0,0 +1,7 @@
# Laboraufgabe "Reduce als *divide and conquer*"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-02-ForkJoinArrayReduce.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-Solutions.html#laboraufgabe-reduce-als-divide-and-conquer)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/12-forkjoin.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/12-forkjoin.html)

View File

@ -0,0 +1,19 @@
# Justfile (https://just.systems/) for starting Maven standard targets
default:
just exec pp.ReduceTask ""
exec class args: compile
mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
# exec class args:
# java -cp target/app.jar {{class}} {{args}}
clean:
mvn clean
compile:
mvn compile
test: compile
mvn test
javadoc:
mvn javadoc:javadoc
package:
mvn package

View File

@ -0,0 +1,72 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pp</groupId>
<artifactId>pp.12.02-ForkJoinArrayReduce</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.ReduceTask</exec.mainClass>
<maven.compiler.release>10</maven.compiler.release>
<lombok.version>edge-SNAPSHOT</lombok.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency><!-- für Unit-Tests -->
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency><!-- für Lombok -->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency><!-- für net.jcip Annotationen -->
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>clean compile exec:java</defaultGoal>
<plugins>
<plugin><!-- für Unit-Tests [mvn test] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin><!-- [mvn compile] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin><!-- [mvn exec:java] -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin><!-- [mvn javadoc:javadoc] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<show>private</show>
<locale>en_US</locale>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,21 @@
package io.dama.ffi.forkjoin;
import java.util.ArrayList;
@SuppressWarnings("serial")
public class ReduceTask {
private static final int ARRAY_LEN = 16;
private static final int SLICE_LEN = 4;
public static void main(String... args) {
var array = new ArrayList<Integer>();
for (var i = 0; i < ARRAY_LEN; i++) {
array.add(i + 1);
}
// initialen ReduceTask erzeugen
// ReduceTask im *Common Thread Pool* starten
// ReduceTask im *Common Thread Pool* starten
// auf Ende warten und Summe ausgeben
}
}

View File

@ -0,0 +1,7 @@
# Laboraufgabe "Reduce als *divide and conquer*"
- [Aufgabenstellung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-02-ForkJoinArrayReduce.html)
- [Musterlösung](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/labs/12-Solutions.html#laboraufgabe-reduce-als-divide-and-conquer)
# Materialien
- [Folien](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/slides/12-forkjoin.html)
- [Skript](https://services.informatik.hs-mannheim.de/~s.leuchter/pp/notes/12-forkjoin.html)

View File

@ -0,0 +1,27 @@
# Justfile (https://just.systems/) for starting Maven standard targets
default: reduceTask
reduceTask:
just exec pp.ReduceTask ""
experiment:
just exec pp.ReduceTaskExperiment ""
generic:
just exec pp.ReduceTaskGeneric ""
threadsnumber:
just exec pp.ReduceTaskThreadsNumber ""
exec class args: compile
mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
# exec class args:
# java -cp target/app.jar {{class}} {{args}}
clean:
mvn clean
compile:
mvn compile
test: compile
mvn test
javadoc:
mvn javadoc:javadoc
package:
mvn package

View File

@ -0,0 +1,72 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pp</groupId>
<artifactId>pp.12.02-ForkJoinArrayReduce_solution</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<exec.mainClass>pp.ReduceTask</exec.mainClass>
<maven.compiler.release>10</maven.compiler.release>
<lombok.version>edge-SNAPSHOT</lombok.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency><!-- für Unit-Tests -->
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<dependency><!-- für Lombok -->
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency><!-- für net.jcip Annotationen -->
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>clean compile exec:java</defaultGoal>
<plugins>
<plugin><!-- für Unit-Tests [mvn test] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin><!-- [mvn compile] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<plugin><!-- [mvn exec:java] -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin><!-- [mvn javadoc:javadoc] -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<show>private</show>
<locale>en_US</locale>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,50 @@
package pp;
import java.util.ArrayList;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
@SuppressWarnings("serial")
public class ReduceTask extends RecursiveTask<Integer> {
private static int ARRAY_LEN = 16;
private static int SLICE_LEN = 4;
private final ArrayList<Integer> array;
private final int start;
private final int end;
ReduceTask(ArrayList<Integer> array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
var sum = 0;
if ((this.end - this.start) <= SLICE_LEN) {
for (var i = this.start; i < this.end; i++) {
sum += this.array.get(i);
}
} else {
var mid = this.start + ((this.end - this.start) / 2);
var left = new ReduceTask(this.array, this.start, mid);
var right = new ReduceTask(this.array, mid, this.end);
left.fork();
right.fork();
sum = left.join() + right.join();
}
return sum;
}
public static void main(String... args) {
var array = new ArrayList<Integer>();
for (var i = 0; i < ARRAY_LEN; i++) {
array.add(i + 1);
}
var task = new ReduceTask(array, 0, array.size());
var sum = ForkJoinPool.commonPool().submit(task).join();
System.out.println("Summe: " + sum);
}
}

View File

@ -0,0 +1,60 @@
package pp;
import java.util.ArrayList;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
@SuppressWarnings("serial")
public class ReduceTaskExperiment extends RecursiveTask<Integer> {
private static int ARRAY_LEN = 0;
private static int SLICE_LEN = 0;
private final ArrayList<Integer> array;
private final int start;
private final int end;
ReduceTaskExperiment(ArrayList<Integer> array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
var sum = 0;
if ((this.end - this.start) <= SLICE_LEN) {
for (var i = this.start; i < this.end; i++) {
sum += this.array.get(i);
}
} else {
var mid = this.start + ((this.end - this.start) / 2);
var left = new ReduceTaskExperiment(this.array, this.start, mid);
var right = new ReduceTaskExperiment(this.array, mid, this.end);
left.fork();
right.fork();
sum = left.join() + right.join();
}
return sum;
}
public static void main(String... args) {
for (ARRAY_LEN = 100; ARRAY_LEN < 10000000; ARRAY_LEN = ARRAY_LEN
* 10) {
for (SLICE_LEN = 4; SLICE_LEN < 128; SLICE_LEN = SLICE_LEN * 2) {
var array = new ArrayList<Integer>();
for (var i = 0; i < ARRAY_LEN; i++) {
array.add(i + 1);
}
var now = System.currentTimeMillis();
var task = new ReduceTaskExperiment(array, 0, array.size());
var sum = ForkJoinPool.commonPool().submit(task).join();
System.out.printf(
"ARRAY_LEN: %d, SLICE_LEN: %d, Summe: %d, Zeit: %d \n",
ARRAY_LEN, SLICE_LEN, sum,
System.currentTimeMillis() - now);
}
}
}
}

View File

@ -0,0 +1,86 @@
package pp;
import java.util.ArrayList;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.function.BiFunction;
@SuppressWarnings("serial")
public class ReduceTaskGeneric<T> extends RecursiveTask<T> {
// Der Typ der Elemente im Container ist T (statt Integer).
// Dieser Typ wird Parameter von ReduceTaskGeneric.
private static int ARRAY_LEN = 16;
private static int SLICE_LEN = 4;
private final ArrayList<T> array;
private final int start;
private final int end;
// generische Lösung: statt + wird die BiFunction aggregateFunc benutzt
// aggregateFunc ist ein Objekt, das die Funktion
// T apply(T x, T y)
// beinhaltet. Sie wird später statt + aufgerufen
private final BiFunction<T, T, T> aggregFun;
// als Start wird ein Ersatz für 0 benötigt. Dieser initiale Wert muss vom
// Typ T
// sein
private final T initAcc;
ReduceTaskGeneric(BiFunction<T, T, T> aggregFun, T initAcc,
ArrayList<T> array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
// generische Lösung: aggregFun und initAcc müssen über den Konstruktor
// übergeben werden
this.aggregFun = aggregFun;
this.initAcc = initAcc;
}
@Override
protected T compute() { // satt Integer T als Rückgabetyp
var accumulator = this.initAcc; // statt 0 initAcc
if ((this.end - this.start) <= SLICE_LEN) {
for (var i = this.start; i < this.end; i++) {
// statt + aggregFun.apply
accumulator = this.aggregFun.apply(accumulator,
this.array.get(i));
}
} else {
var mid = this.start + ((this.end - this.start) / 2);
var left = new ReduceTaskGeneric<>(this.aggregFun, this.initAcc,
this.array, this.start, mid);
var right = new ReduceTaskGeneric<>(this.aggregFun, this.initAcc,
this.array, mid, this.end);
left.fork();
right.fork();
// statt + aggregFun.apply
accumulator = this.aggregFun.apply(left.join(), right.join());
}
return accumulator;
}
public static void main(String... args) {
var array = new ArrayList<Integer>();
for (var i = 0; i < ARRAY_LEN; i++) {
array.add(i + 1);
}
// Hier wird die aggregFun als Lambda-Ausdruck übergeben: (a, b) -> a +
// b
// Der Typ-Parameter von ReduceTaskGeneric wird dementsprechend auf
// Integer
// festgelegt.
// Der initiale Wert des +-Akkumulators ist 0
var task = new ReduceTaskGeneric<>(//
((a, b) -> a + b), // Hier wird die aggregFun als
// Lambda-Ausdruck übergeben: +
0, // Der initiale Wert des +-Akkumulators ist 0.
array, 0, array.size());
ForkJoinPool.commonPool().invoke(task);
// seit Java 8 alternativ: task.invoke();
var sum = task.join();
System.out.println("Summe: " + sum);
}
}

View File

@ -0,0 +1,56 @@
package pp;
import java.util.ArrayList;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
@SuppressWarnings("serial")
public class ReduceTaskThreadsNumber extends RecursiveTask<Integer> {
private static int ARRAY_LEN = 280;
private static int SLICE_LEN = ARRAY_LEN / ForkJoinPool.commonPool().getParallelism();
private static int instanceCounter = 0;
private final ArrayList<Integer> array;
private final int start;
private final int end;
ReduceTaskThreadsNumber(ArrayList<Integer> array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
instanceCounter++;
}
@Override
protected Integer compute() {
var sum = 0;
if ((this.end - this.start) <= SLICE_LEN) {
for (var i = this.start; i < this.end; i++) {
sum += this.array.get(i);
}
} else {
var mid = this.start + ((this.end - this.start) / 2);
var left = new ReduceTaskThreadsNumber(this.array, this.start, mid);
var right = new ReduceTaskThreadsNumber(this.array, mid, this.end);
left.fork();
right.fork();
sum = left.join() + right.join();
}
return sum;
}
public static void main(String... args) {
var array = new ArrayList<Integer>();
for (var i = 0; i < ARRAY_LEN; i++) {
array.add(i + 1);
}
var task = new ReduceTaskThreadsNumber(array, 0, array.size());
var sum = ForkJoinPool.commonPool().submit(task).join();
System.out.println("Summe: " + sum);
System.out.println("instanceCounter: " + instanceCounter);
System.out.println(
"Parallelism: " + ForkJoinPool.commonPool().getParallelism());
System.out.println("ARRAY_LEN: " + ARRAY_LEN);
}
}