0

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

Community
  • 1
  • 1
andrew
  • 9,313
  • 7
  • 30
  • 61
  • 2
    "region of a thousand threads." Overkill. – nanofarad Aug 15 '13 at 22:50
  • 1
    `ArrayList`??? You can't pass a primitive type to generics, only object types. – gparyani Aug 15 '13 at 22:55
  • You should print and post the stack trace. My guess is the problem is that you aren't using a thread safe collection. – samlewis Aug 15 '13 at 22:56
  • You have three options for thread safety: 1. Change from `ArrayList` to `Vector`. 2. Wrap the ArrayList in a synchronized decorator (using `Collections.synchronizedList()`). 3. Change from an `ArrayList` to a `java.util.concurrent.CopyOnWriteArrayList`. – gparyani Aug 15 '13 at 22:58
  • Thats a typo on my part it should have been written as adekcz pointed out. What im looking for is a way to write to the list, (It does not specifically have to be in arraylist) from the thread – andrew Aug 15 '13 at 22:59
  • It's really best if you copy-paste your code into here, rather than re-typing it. If you post code with syntax errors (such as missing semi-colons and missing braces), it makes it that much harder for anyone to help you out. – Dawood ibn Kareem Aug 15 '13 at 23:27
  • Well, to pedantic, threads cannot return anything because they cannot be called. – Martin James Aug 15 '13 at 23:58

2 Answers2

3

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.

tFrisch
  • 133
  • 4
1
ArrayList<Integer> outputints = new ArrayList<Integer>();

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

adekcz
  • 340
  • 2
  • 13
  • 3
    Okay, yes, this is the NPE. But `ArrayList` isn't thread (or "thred") safe so this doesn't solve the problem. – Boris the Spider Aug 15 '13 at 22:54
  • Boris is right, you should use [Collections.synchronizedList](http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)) instead (or any other thread-safe list) – BackSlash Aug 15 '13 at 22:58
  • I'd actually changed that line from ArrayList someStrings; to ArrayList outputints for the purpose of the mock code without realizing that wasn't allowed. (I'm new to Java). Even so, this was the NPE cause. – andrew Aug 17 '13 at 09:32