0

以下代码编译但在运行时导致空指针异常。我最好的猜测是 outputInts 对每个线程都不“可见”,因此无法写入。

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

 }

我读过我应该使用可调用来实现这一点,但我不明白这是如何实现的。此外,返回值的 java Runnable run() 方法之类的示例似乎表明我可以使用可调用对象运行少数线程,而我可能需要在一千个线程区域的某个地方。

我正在寻求帮助以使上述实现工作或外行的术语指南,以了解如何通过可调用来实现

4

2 回答 2

3

Brian Goetz 写了一本很棒的书,名为 Java Concurrency in Practice,其中深入介绍了这一点。您应该考虑使用 Completion Service,它是一种 Executor。这是示例 java 代码:

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

您可以使用 take() 方法从 ExecutorCompletionService 检索已完成的 Futures。在 FutureTask 上调用 get() 方法来获取结果。这些类可以使用泛型参数化以实现类型安全和更大的代码灵活性。

于 2013-08-15T23:19:19.417 回答
1
ArrayList<Integer> outputints = new ArrayList<Integer>();

您的 IDE 应该保护您免受此类错误的影响...

于 2013-08-15T22:52:51.530 回答