andrew
andrew

Reputation: 9583

In java how can I get a return value from a thread?

The following code compiles but results in a null pointer exception at run time. My best guess is outputInts is not "visible" to each thread and therefore cannot be written to.

public class myClass{

ArrayList<int> outputints

public void foo(int start, int end) {
    for (int i = start; i <= end; i++) {
          bar(i);
        }

private void bar(int i) {
    class OneShotTask implements Runnable {
        int i;
        OneShotTask(int j) {
            i = j;
        }
        @Override
        public void run() {
            try {
                    System.out.println(i);
                    outputints.add(i);      //null pointer exception caused here
                }
            } catch (Exception e) {
                System.out.println(e.toString());
            }

        }
    }
    Thread t = new Thread(new OneShotTask(j));
    t.start();
  }

 }

I've read that I should be using a callable to achieve this but I don't understand how this is implemented. Also the examples like java Runnable run() method returning a value seem to suggest that I can run a handful of threads using a callable where I may need somewhere in the region of a thousand threads.

I'm looking for help in getting either the above implementation to work or a layman's terms guide to how it can be achieved with a callable

Upvotes: 0

Views: 317

Answers (2)

tFrisch
tFrisch

Reputation: 133

Brian Goetz wrote a terrific book called Java Concurrency in Practice that covers this in depth. You should look into using a Completion Service, which is a type of Executor. Here is the example java code:

     void solve(Executor e, Collection<Callable<Result>> solvers)
         throws InterruptedException, ExecutionException {
           CompletionService<Result> ecs = new ExecutorCompletionService<Result>(e);
           for (Callable<Result> s : solvers)
             ecs.submit(s);
           int n = solvers.size();
           for (int i = 0; i < n; ++i) {
             Result r = ecs.take().get();
               if (r != null)
                 use(r);
 }
}

You can retrieve completed Futures from the ExecutorCompletionService with the take() method. The method get() is called on the FutureTask to get the result. These classes can be parameterized with generics for type safety, and greater code flexibility.

Upvotes: 3

adekcz
adekcz

Reputation: 410

ArrayList<Integer> outputints = new ArrayList<Integer>();

your IDE should shield you from this kind of errors...

Upvotes: 1

Related Questions