Как использовать более одного метода Compute в ForkJoin Framework Javaello
Мне нужно решить более простую проблему. Мне нужно решить параллельное суммирование 1000 случайных значений X и 1000 случайных значений Y. Я использую Parallel ForkJoin фреймворк Java. При использовании метода с одним вычислением невозможно вычислить суммирование значений X и Y на совершенно разных маршрутах.
Более того, мне нужно вычислить сумму X * Y. То есть значения Σxiyi, НО X, пройденные одним потоком, назначают отдельную задачу, а Y вставляется в пул потоков как отдельная задача. Так как же можно одновременно умножить значения X и Y, то есть X * Y ==> (X = 100, Y = 150)? Первый поток работает на X, а второй на Y.
Код:
открытый класс RegressionLineForkJoin {
//private static final ForkJoinPool forkJoinPool = new ForkJoinPool( 2 ); // use only 2 processors
private static Random r = new Random( );
private static final int NR_OF_VALUES = 1000; // X & Y VALUES
private static final int THRESHOLD = 100; // need to calculate Threshold value.
private static class RegressionLineForkJoinTask extends RecursiveTask<Integer>
{
private int m_Start;
private int m_End;
public RegressionLineForkJoinTask(int a_start,int a_end)
{
this.m_Start = a_start;
this.m_End = a_end;
}
public Integer compute()
{
Integer Sum = 0;
if(this.m_End - this.m_Start < THRESHOLD)
{
calculateSum(this.m_Start,this.m_End);
}
else
{
int split = (this.m_Start + this.m_End)/2;
RegressionLineForkJoinTask oRegressionLineTask_1 = new RegressionLineForkJoinTask(this.m_Start , split);
RegressionLineForkJoinTask oRegressionLineTask_2 = new RegressionLineForkJoinTask( split+1 , this.m_End);
// Invoke the tasks in parallel
invokeAll(oRegressionLineTask_1,oRegressionLineTask_2);
Sum += oRegressionLineTask_1.join();
Sum += oRegressionLineTask_2.join();
//Sum
}//end of else
return Sum;
}
public static void main(String[ ] args)
{
RegressionLineForkJoinTask oRegressionLineForkJoinTask_X = new RegressionLineForkJoinTask( 0,NR_OF_VALUES );
RegressionLineForkJoinTask oRegressionLineForkJoinTask_Y = new RegressionLineForkJoinTask( 0,NR_OF_VALUES );
Integer Sum_X_Values = forkJoinPool.invoke(oRegressionLineForkJoinTask_X);
Integer Sum_Y_Values = forkJoinPool.invoke(oRegressionLineForkJoinTask_Y);
System.out.println("in main after forkjoin.invoke()");
}
private static double nextRandomFunctionValue(int a_startInex,int a_endIndex)
{
double randomValue = 0.0;
randomValue = a_startInex + ( a_endIndex - a_startInex ) * r.nextDouble( );
return randomValue;
}//end of nextRandomFunctionValue
private static double calculateSum(int a_startIndex, int a_endIndex)
{
double sumValue = 0.0;
double RandomeValue = 0.0;
for(int index = a_startIndex; index< a_endIndex; index++)
{
RandomeValue = nextRandomFunctionValue(a_startIndex,a_endIndex);
sumValue += RandomeValue;
}//end of for
return sumValue;
}
}
}
1 ответ
Вы должны иметь 2 массива int xs
а также ys
создан вне ваших задач и задан в качестве параметров ваших задач. Итак, ваш конструктор
RegressionLineForkJoinTask(int a_start,int a_end)
было быRegressionLineForkJoinTask(int a_start,int a_end, int[] vector)
с вектором xs
или же ys
, Они будут использовать vector
сюда:
public Integer compute() {
int sum = 0;
if(this.m_End - this.m_Start < THRESHOLD) {
for (int i = this.m_Start; i < this.m_End; i++)
sum += this.m_vector[i];
} /* else split task as before */
}
Тогда на той же основе вы можете иметь ProductRecursiveForkJoinTask
работа с двумя векторами с этим конструктором:RegressionLineForkJoinTask(int a_start,int a_end, int[] vectorA, int[] vector B)
с помощью этого метода вычисления:
public Integer compute() {
int sum = 0;
if(this.m_End - this.m_Start < THRESHOLD) {
for (int i = this.m_Start; i < this.m_End; i++)
sum += this.m_vectorA[i] * this.m_vectorB[i];
} /* else split task as before */
}