Почему эта простая вилка Java не работает?

Я собираюсь протестировать этот пул forkjoin, но он не работает нормально. Интересно, почему?

Это класс, который я сделал, чтобы получить массив и добавить 3 к его элементам:

import static java.util.concurrent.ForkJoinTask.invokeAll;
import java.util.concurrent.RecursiveAction;

public class t extends RecursiveAction{

    private final int array[];
    private final int th=4;

    public t (int array[]){
        this.array=array;
    }

    protected void compdir(){

        for (int i=0;i<array.length;i++){
            array[i]=array[i]+3;
        }
    }

    @Override
    protected void compute(){
        int cont=1;

        System.out.println("array="+(array[0])+","+array[array.length-1]);


        System.out.println("cont="+cont);
        if (array.length<th){      
            compdir();

        } else {

            int spil=(array[0]+array[(array.length-1)])/2;
            int array1[]=new int[spil];
            int array2[]=new int[spil];
            for (int i=0;i<array1.length;i++){
                array1[i]=array[i];
            }
            for (int i=0;i<array2.length;i++){
                array2[i]=array[i+(array1.length)];
            }
            invokeAll(new t(array1) , new t(array2));
            cont++;
        }
    }

}

и это основной класс:

package nt;

import java.util.concurrent.ForkJoinPool;

public class Nt {


    public static void main(String[] args) {
        int processors = Runtime.getRuntime().availableProcessors();
        System.out.println(Integer.toString(processors) + " processor"
                + (processors != 1 ? "s are " : " is ")
                + "available");

        int arr[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
        t test=new t(arr);

        ForkJoinPool pool = new ForkJoinPool();

        long startTime = System.currentTimeMillis();
        pool.invoke(test);
        long endTime = System.currentTimeMillis();

        System.out.println("Takes " + (endTime - startTime) + 
                " milliseconds.");

    }

}

person user3252955    schedule 30.01.2014    source источник
comment
Было бы полезно, если бы вы объяснили, что не работает нормально.   -  person pveentjer    schedule 30.01.2014
comment
Исключение в потоке main java.lang.ArrayIndexOutOfBoundsException в sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) в sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) в sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java )   -  person user3252955    schedule 30.01.2014
comment
Можете ли вы добавить это к своему исходному вопросу, чтобы мы могли увидеть полную трассировку стека.   -  person pveentjer    schedule 30.01.2014
comment
Да, конечно. и спасибо заранее.   -  person user3252955    schedule 30.01.2014
comment
Исключение в потоке main java.lang.ArrayIndexOutOfBoundsException в sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) в sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) в sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java ) в java.lang.reflect.Constructor.newInstance(Constructor.java:526) в java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:536) в java.util.concurrent.ForkJoinTask.reportResult(ForkJoinTask.java: 596)   -  person user3252955    schedule 30.01.2014
comment
в java.util.concurrent.ForkJoinTask.reportResult(ForkJoinTask.java:596) в java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:640) в java.util.concurrent.ForkJoinPool.invoke(ForkJoinPool.java:1521 ) в nt.Nt.main(Nt.java:22)   -  person user3252955    schedule 30.01.2014
comment
Можете ли вы отредактировать исходный вопрос. Комментарии бесполезны для сложного текста, такого как трассировка стека или код. Также ваш код не завершен. Итак, вы можете изменить свой исходный вопрос и опубликовать полный код и полную трассировку стека. Если это не сработает, просто создайте новый ответ, в котором вы разместите всю свою информацию.   -  person pveentjer    schedule 30.01.2014
comment
Ok. секундочку пожалуйста...   -  person user3252955    schedule 30.01.2014
comment
Извините. не могу вставить трассировку стека. Но это мой полный код.   -  person user3252955    schedule 30.01.2014


Ответы (1)


Вы создаете новый массив для каждой задачи. Хотя содержимое этих новых массивов установлено таким же, как и во входном массиве, изменение значений в этих новых массивах НЕ повлияет на значения в входной массив.

Вы должны убедиться, что ВСЕ задачи работают ТОЛЬКО на массиве INPUT. Задачи отличаются только теми элементами входного массива, которые их интересуют. В этом примере диапазон, над которым работает каждая задача, определяется «min» и «max»:

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;

public class Nt {
    public static void main(String[] args) {
        int processors = Runtime.getRuntime().availableProcessors();
        System.out.println(Integer.toString(processors) + " processor"
            + (processors != 1 ? "s are " : " is ")
            + "available");

        int arr[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
        t test=new t(arr);

        ForkJoinPool pool = new ForkJoinPool();

        long startTime = System.currentTimeMillis();
        pool.invoke(test);
        long endTime = System.currentTimeMillis();

        System.out.println("Takes " + (endTime - startTime) + 
            " milliseconds.");

    }
}
class t extends RecursiveAction{


    private final int array[];
    private final int min;
    private final int max;
    private final int th=4;

    public t (int array[]){
        this(array, 0, array.length);
    }

    public t (int array[], int min, int max){
        this.array=array;
        this.min = min;
        this.max = max;

        System.out.println("Task to handle range "+min+" to "+max);
    }

    protected void compdir(){

        for (int i=min;i<max;i++){
            array[i]=array[i]+3;
        }
    }

    @Override
    protected void compute(){
        if (max-min<th) {      
            compdir();
        } else {

            int center = min + (max - min) / 2;
            invokeAll(new t(array, min, center) , new t(array, center+1, max));
        }
    }

}
person Marco13    schedule 30.01.2014