2013-08-15 3 views
0

Следующий код компилирует, но приводит к исключению нулевого указателя во время выполнения. Мое лучшее предположение: outputInts не «видимо» для каждого потока и поэтому не может быть записано.В java, как я могу получить возвращаемое значение из потока?

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() method returning a value, по-видимому, предполагают, что я могу запускать несколько потоков с помощью вызываемого, где мне может понадобиться где-то в области тысячи потоков.

Я ищу помощь в получении либо выше осуществления на работу или термины руководства непрофессионала к тому, как это может быть достигнуто с отзывным

+2

«регион из тысячи нитей». Overkill. – hexafraction

+1

'ArrayList ' ??? Вы не можете передавать примитивный тип в generics, только типы объектов. – gparyani

+0

Вы должны распечатать и опубликовать трассировку стека. Я предполагаю, что проблема заключается в том, что вы не используете потокобезопасную коллекцию. – samlewis

ответ

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

вашего IDE должен оградить вас от такого рода ошибок. ..

+3

Хорошо, да, это NPE. Но 'ArrayList' не является безопасным потоком (или« thred »), поэтому это не решает проблему. –

+0

Борис прав, вы должны использовать [Collections.synchronizedList] (http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList (java.util.List)) вместо этого (или любой другой нитевидный список) – BackSlash

+0

Посмотреть мой комментарий. – gparyani

3

Брайан Гетц написал потрясающую книгу под названием Java Concurrency на практике, которая охватывает это в глубину. Вы должны изучить использование службы завершения, которая является типом 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); 
} 
} 

Вы можете получить завершена Фьючерс из ExecutorCompletionService с методом отбора(). Метод get() вызывается в FutureTask для получения результата. Эти классы могут быть параметризованы с помощью дженериков для безопасности типов и большей гибкости кода.

Смежные вопросы