1

我仍在学习如何在 Java 中使用 Future 和 Callable。偶然发现这个问题:

说我有课:

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

我想要做的是,打破在单独线程中运行的请求的一部分,因为每个请求 Id 都是单独的搜索过程。所以我试图通过将结果存储在未来对象中来利用 Java 池。

我感到困惑的是,在这种情况下,未来将如何运作?对于每个线程完成,它会保存结果吗?在所有过程完成后,我可以循环未来对象以获得正确的结果?

此外,不能保证进程会按顺序运行(1、2、3、4 等),对吧?如果是这种情况,那么如果我想将每个原始请求与未来结果相关联,那么最好的策略是什么?

请指教。

谢谢

4

2 回答 2

2

此外,不能保证进程会按顺序运行(1、2、3、4 等),对吧?如果是这种情况,那么如果我想将每个原始请求与未来结果相关联,那么最好的策略是什么?

您无法知道后台线程启动和完成的顺序,但是当您循环遍历您的 result-ArrayList 时,您当然会按照您提交它们的顺序获得结果。这里唯一可能发生的事情是 .get() 将阻塞,直到此未来对象的特定结果可用(如果尚不可用)。

于 2010-10-29T15:06:30.240 回答
0

您应该创建 SynchronizedMap 并将其与 Request 一起传递给构造函数中的 TaskWorker。TaskWorker 应在完成作业后将 Request 和 Result 添加到地图中。

您不必循环 Futures 来获得结果,只需确保所有工作都已完成。

于 2010-10-29T14:54:22.613 回答