Java Future 多线程如何返回结果?

发布于 2024-09-29 23:27:30 字数 1676 浏览 5 评论 0原文

我仍在学习如何在 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 都是单独的搜索进程。 所以我尝试通过将结果存储在 future 对象中来利用 Java 池。

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

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

请指教。

谢谢

I am still learning about using Future and Callable in Java.
Stumble into this question:

Say I have class:

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

And here is the main method:

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

What I am trying to do is, breaking a part the request to run in separate thread since each of the request Id is separate Search process.
So I am trying to utilize Java pooling, by storing the result in the future object.

The thing I am confused is, how does future will work in this case?
For each thread completion, is it going to hold the results? And after all the process finish, I can just loop future object to get the results right?

Also, there is no guarantee that process will run in order (1,2,3,4,etc), right?
If that the case, then what is the best strategy if I want to associate each original request with the future result?

Please advise.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寄意 2024-10-06 23:27:30

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

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

Also, there is no guarantee that
process will run in order
(1,2,3,4,etc), right? If that the
case, then what is the best strategy
if I want to associate each original
request with the future result?

You cannot know the order in which the background threads are started and finished, but when you loop through your result-ArrayList you will get, of course, the results in the order you submitted them. The only thing that can happen here is that the .get() will block until the particular result of this future-object is available, if not already available.

開玄 2024-10-06 23:27:30

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

您不必循环 Futures 来获取结果,只需确保所有作业都已完成即可。

You should create SynchronizedMap and pass it to TaskWorker in constructor together with a Request. TaskWorker should add Request and Result to the map when it finishes the job.

You dont have to loop Futures to get results, just make sure all jobs are finished.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文