Как многопоточность Java Future возвращает результат? - PullRequest
1 голос
/ 29 октября 2010

Я все еще учусь использовать Future и Callable в Java. Наткнуться на этот вопрос:

Скажи, что у меня есть класс:

TaskWorker implements Callable {
  public String id;
  public TaskWorker(String id) {
     this.id = id;
  }

  public Documents call() trows Exception {
       //Assume here, that Search and Doc are my own method to search and retrieve docs
       Search search =  new Search();
       Documents docResult = search.process(id);

       //think about documents has getDocs
       //docResult.getDocs() will return number of document found from search

       return docResult;
  }
}

А вот основной метод:

public static void main(String[] args) {
   //assume here, that I build in request contains many Id

   Request request = new Request();
   request.process;

   ExecutorService service = Executors.newFixedThreadPool(3);
   List<Future<Documents>> result = new ArrayList<Future<Documents>>();

   for (int i=0;i<request.length;i++) {
       Callable<Documents> worker = new TaskWorker(request.getId[i]);
       Future<Documents> submit = executor.submit(worker);
       result.add(submit);
   }

   Response response = new Response();
   ArrayList<Documents> docList = new ArrayList<Documents>();

   for (Future<Documents> future:result) {
     docList.add(future.get().getDocs());
   }

   response.setDocuments(docList);
}

Я пытаюсь разбить часть запроса на выполнение в отдельном потоке, поскольку каждый из идентификаторов запроса является отдельным процессом поиска. Поэтому я пытаюсь использовать пул Java, сохраняя результат в будущем объекте.

Меня смущает то, как будущее будет работать в этом случае? Для каждого завершения потока он будет содержать результаты? И после завершения процесса я могу просто зациклить будущий объект, чтобы получить правильные результаты?

Кроме того, нет никакой гарантии, что процесс будет работать по порядку (1,2,3,4 и т. Д.), Верно? Если это так, то какова лучшая стратегия, если я хочу связать каждый исходный запрос с будущим результатом?

Пожалуйста, сообщите.

Спасибо

Ответы [ 2 ]

2 голосов
/ 29 октября 2010

Кроме того, нет никакой гарантии, что процесс будет работать по порядку (1,2,3,4 и т. Д.), Верно?Если это так, то какова лучшая стратегия, если я хочу связать каждый исходный запрос с будущим результатом?

Вы не можете знать порядок, в котором фоновые потоки запускаются и заканчиваются, но когдаВы перебираете свой результат-ArrayList, вы, конечно, получите результаты в том порядке, в котором вы их отправили.Единственное, что здесь может произойти, это то, что .get () будет блокироваться, пока не будет доступен конкретный результат этого объекта будущего, если он еще не доступен.

0 голосов
/ 29 октября 2010

Вы должны создать SynchronizedMap и передать его в TaskWorker в конструкторе вместе с запросом. TaskWorker должен добавить запрос и результат на карту после завершения работы.

Вам не нужно зацикливать Futures для получения результатов, просто убедитесь, что все задания завершены.

...