8

I'm trying to return a 2d array from call(), I'm having some issues. My code so far is:

//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;                                  
    }

This code compiles, this is not returning my array. I'm sure I'm probably using the wrong syntax, but I can't find any good examples.

EDIT: changed it a bit

user650309
  • 2,639
  • 7
  • 28
  • 47
  • What is it returning? Where is length coming from? Where are Array1 and Array2 coming from? – Joseph Ottinger Apr 01 '11 at 16:50
  • I'm pretty sure `answer = multiplyArray(Array1, Array2, length,);` will not compile since there is an extra `,`. You should post more Code, because I don't think it is possible to make an assumption here without guessing. – Simon Woker Apr 01 '11 at 16:52
  • What is invoking the call() method? – dontocsata Apr 01 '11 at 16:53

3 Answers3

10

Here's some code demonstrating use of the Callable<> interface:

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]));
    }
}
}

What this does is construct an object that can be submitted to an executor service. It's fundamentally the same as a Runnable, except that it can return a value; what we're doing here is creating an ExecutorService with two threads, then submitting this callable to the service.

The next thing that happens is the result.get(), which will block until the callable returns.

You probably shouldn't do the Thread management yourself.

Joseph Ottinger
  • 4,911
  • 1
  • 22
  • 23
  • This is very useful, but how is it possible to send objects to the callable object? I need to send two arrays to it. – user650309 Apr 01 '11 at 17:04
  • You could pass them in at construction, or extend the Callable interface to use instance-local arrays. – Joseph Ottinger Apr 01 '11 at 17:30
  • Great answer, and kudos for promoting the ExecutorService usage. There really aren't many places one should be using Thread ever again. – Java Drinker Apr 01 '11 at 18:13
6

Adding to Joseph Ottinger's answer, to pass values to be used inside Callable's call() method, you can use closures:

    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));
        }
    }
Marimuthu Madasamy
  • 13,126
  • 4
  • 30
  • 52
  • I have to say a big thank you to both Joseph Ottinger and Marimuthu Madasamy. I got there in the end with your help. – user650309 Apr 01 '11 at 19:30
2

In addition to Joseph's excellent answer, note that your method signature is int[][] call(int[][]). If you reference the Callable javadoc you'll see that the Callable's call() method does not take any arguments. So your method is an overload, not an override, and so won't be called by anything that is calling Callable's call() method.

QuantumMechanic
  • 13,795
  • 4
  • 45
  • 66
  • heh, thank you. I figured it was just easier to show correct usage rather than try to figure out what was actually going on in the (slightly incomplete) example code. – Joseph Ottinger Apr 01 '11 at 17:03
  • As the Germans say: "Da liegt der Hund begraben" - this is where the problem lies. – Joel Shemtov Nov 07 '14 at 09:28