Как вернуть объект из Callable () - PullRequest
7 голосов
/ 01 апреля 2011

Я пытаюсь вернуть 2d массив из call (), у меня возникли некоторые проблемы.Мой код на данный момент:

//this is the end of main   
Thread t1 = new Thread(new ArrayMultiplication(Array1, Array2, length));
t1.start(); 
}

    public int[][] call(int[][] answer)
    {       

    int[][] answer = new int[length][length]; 

    answer = multiplyArray(Array1, Array2, length); //off to another function which returns the answer to here  

    return answer;                                  
    }

Этот код компилируется, он не возвращает мой массив.Я уверен, что, возможно, я использую неправильный синтаксис, но я не могу найти хороших примеров.

РЕДАКТИРОВАТЬ: немного изменил

Ответы [ 3 ]

9 голосов
/ 01 апреля 2011

Вот код, демонстрирующий использование интерфейса Callable <>:

public class test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
    Callable callable = new Callable() {
        @Override
        public int[][] call() throws Exception {
            int[][] array = new int[5][];
            for (int i = 0; i < array.length; i++) {
                array[i] = new int[]{5 * i, 5 * i + 1, 5 * i + 2, 5 * i + 3};
            }

            return array;
        }
    };

    ExecutorService service = Executors.newFixedThreadPool(2);
    Future<int[][]> result = service.submit(callable);

    int[][] intArray = result.get();
    for (int i = 0; i < intArray.length; i++) {
        System.out.println(Arrays.toString(intArray[i]));
    }
}
}

Для этого создается объект, который может быть передан в службу исполнителя. По сути, он такой же, как и Runnable, за исключением того, что он может возвращать значение; то, что мы делаем здесь, это создание ExecutorService с двумя потоками, а затем отправка этого вызываемого в службу.

Следующим, что происходит, является result.get (), который будет блокироваться до тех пор, пока не будет вызван вызываемый объект.

Вы, вероятно, не должны выполнять управление потоками самостоятельно.

5 голосов
/ 01 апреля 2011

Добавляя к ответу Джозефа Оттингера, для передачи значений, которые будут использоваться внутри метода calllable call (), вы можете использовать замыкания:

    public static Callable<Integer[][]> getMultiplierCallable(final int[][] xs,
            final int[][] ys, final int length) {
        return new Callable<Integer[][]>() {
            public Integer[][] call() throws Exception {
                Integer[][] answer = new Integer[length][length];
                answer = multiplyArray(xs, ys, length);
                return answer;
            }
        };
    }

    public static void main(final String[] args) throws ExecutionException,
            InterruptedException {
        final int[][] xs = {{1, 2}, {3, 4}};
        final int[][] ys = {{1, 2}, {3, 4}};
        final Callable<Integer[][]> callable = getMultiplierCallable(xs, ys, 2);
        final ExecutorService service = Executors.newFixedThreadPool(2);
        final Future<Integer[][]> result = service.submit(callable);
        final Integer[][] intArray = result.get();
        for (final Integer[] element : intArray) {
            System.out.println(Arrays.toString(element));
        }
    }
2 голосов
/ 01 апреля 2011

В дополнение к превосходному ответу Джозефа, обратите внимание, что подпись вашего метода int[][] call(int[][]). Если вы ссылаетесь на javadoc Callable, вы увидите, что метод Callable call() не принимает никаких аргументов. Таким образом, ваш метод является перегрузкой, а не переопределением, и поэтому не будет вызываться чем-либо, что вызывает Callable 'call() метод.

...