C'è una classe Sum che uso spesso con questi metodi:
codice:
import java.util.concurrent.*;
class Sum extends RecursiveTask<Double> {
final int seqThresHold = 500;
double[] data;
int start, end;
Sum(double[] vals, int s, int e ) {
data = vals;
start = s;
end = e;
}
protected Double compute() {
double sum = 0;
if((end - start) < seqThresHold) {
for(int i = start; i < end; i++) sum += data[i];
}
else {
int middle = (start + end) / 2;
Sum subTaskA = new Sum(data, start, middle);
Sum subTaskB = new Sum(data, middle, end);
subTaskA.fork();
subTaskB.fork();
sum = subTaskA.join() + subTaskB.join();
}
return sum;
}
}
class RecurTaskDemo {
public static void main(String args[]) {
ForkJoinPool fjp = new ForkJoinPool();
double[] nums = new double[5000];
for(int i=0; i < nums.length; i++)
nums[i] = (double) (((i%2) == 0) ? i : -i) ;
Sum task = new Sum(nums, 0, nums.length);
double summation = fjp.invoke(task);
System.out.println("Summation " + summation);
}
}
Il codice funziona ma è scomodo da utilizzare in quanto tutte le volte che devo apportare una modifica all'algoritmo che racchiude la classe (nell'esempio la somma di numeri di un vettore) mi devo portare dietro tutto il resto della classe. Per questo motivo vorrei creare una classe Sum magari rinominata con qualcosa di più originale (ad es. Multiprocessione, ScomposizioneParallela o qualcosa di originale, ecc...) che posso importare nel mio pakage all'occorrenza ed utilizzare in diverse circostanze. In sostanza mi serve un metodo che accetti in input un altro metodo sequenziale trasformabile con la tecnica della ricorsione in pura e semplice programmazione parallela.
Qui sotto un mio tentativo che vi aiuta a capire come vorrei affrontare il problema che però non funziona:
codice:
import java.util.concurrent.*;
class Sum extends RecursiveTask<Double> {
final int seqThresHold = 1000;
double[] data;
int start, end;
Sum(double[] vals, int s, int e) {
data = vals;
start = s;
end = e;
}
protected Double compute() {
double sum = 0;
if ((end - start) < seqThresHold) {
MetodoSomma.MetodoSomma(data, start, end);
} else {
int middle = (start + end) / 2;
Sum subTaskA = new Sum(data, start, middle);
Sum subTaskB = new Sum(data, middle, end);
subTaskA.fork();
subTaskB.fork();
sum = subTaskA.join() + subTaskB.join();
}
return sum;
}
}
class MeotodoSomma{
private void MetodoSomma(double[] data, int start, int end) {
double sum = 0;
for (int i = start; i < end; i++) {
sum += data[i];
for (int j = start; j < end; j++) {
sum += data[j];
sum -= data[j];
}
}
}
}
class RecurTaskDemo {
public static void main(String args[]) {
double[] nums = new double[4000];
for (int i = 0; i < nums.length; i++)
nums[i] = (double) (((i % 2) == 0) ? i : -i);
ForkJoinPool fjp = new ForkJoinPool();
Sum task = new Sum(nums, 0, nums.length);
double summation = fjp.invoke(task);
System.out.println("Summation " + summation);
}
}
Detto in modo più semplice vorrei programmare in modo sequenziale creando un metodo che trasforma il mio metodo sequenziale in programmazione parallela senza dover estendere tutte le volte RecursiveTask, istanziare un ForkJoinPool, ecc...
Per essere ancora più chiaro mi servirebbe un sistema qualsiasi per evitare di riscrivere tutte le volte il contenuto di 'else'. Vorrei dividere il codice che regola il calcolo (somma di numeri) da quello che esegue la scomposizione del carico di lavoro su più processori (RecursiveTask, ForkJoinPool).

