英文:
Best way to use Future in java
问题
我有一组作业,我正在使用执行器框架和Future来提交。假设我有100个Future。目前,我正在使用Future.get并使用输出进行后续处理。但为了进一步优化,我想改变流程如下:
- 遍历一组未来任务,并在未来任务完成后立即开始使用结果。我正在阅读API文档以了解如何更好地完成我所寻找的内容,但仍然想知道是否有更好的方法可以实现我所期望的目标。
以下是示例代码:
public class ImplCallable implements Callable<String> {
int timeOut;
ImplCallable(int timeOut) {
this.timeOut=timeOut;
}
public String call() throws Exception {
Thread.sleep(timeOut);
return Thread.currentThread().getName();
}
}
// 主类
public class MainProg {
public static void main(String...args) throws Exception {
long startTimeInMillis = System.currentTimeMillis();
ImplCallable callable1 = new ImplCallable(1000);
ImplCallable callable2 = new ImplCallable(2000);
ExecutorService service = Executors.newFixedThreadPool(4);
Future<String> task1 = service.submit(callable1);
Future<String> task2 = service.submit(callable2);
List<Future<String>> futureList = new ArrayList();
futureList.add(task1);
futureList.add(task2);
String retVal;
for(Future<String> task:futureList) {
retVal = task.get();
// 使用retVal进行一些操作
}
long endTimeInMillis = System.currentTimeMillis();
System.out.println("代码所用时间 - " + (endTimeInMillis-startTimeInMillis) + "-毫秒");
}
}
基本上,我不想使用**Future.get()**并等待其完成。我希望知道任何一个任务是否完成,并尽快使用结果。
英文:
I have a set of jobs which I am submitting using executor framework and Future. Let's say that I have 100 futures. As of now, I am using Future.get and using the output for subsequent processing. However for further tuning, I want to change the flow as below:
- iterate through the set of future tasks and start consuming the result as soon as a future task is complete. I am reading the API doc to understand what might be a good way to accomplish this but reaching out to see if there is a better way to accomplish what I am looking for.
Here is the sample code:
public class ImplCallable implements Callable<String> {
int timeOut;
ImplCallable(int timeOut) {
this.timeOut=timeOut;
}
public String call() throws Exception {
Thread.sleep(timeOut);
return Thread.currentThread().getName();
}
}
and the main class:
public class MainProg {
public static void main(String...args) throws Exception {
long startTimeInMillis = System.currentTimeMillis();
ImplCallable callable1 = new ImplCallable(1000);
ImplCallable callable2 = new ImplCallable(2000);
ExecutorService service = Executors.newFixedThreadPool(4);
Future<String> task1 = service.submit(callable1);
Future<String> task2 = service.submit(callable2);
List<Future<String>> futureList = new ArrayList();
futureList.add(task1);
futureList.add(task2);
String retVal;
for(Future<String> task:futureList) {
retVal = task.get();
//do something with the retVal
}
long endTimeInMillis = System.currentTimeMillis();
System.out.println("time taken by code - " + (endTimeInMillis-startTimeInMillis) + "-ms");
}
}
Basically I don't want to use Future.get() and wait for its completion. I want to know if either of the task is complete and use the result as soon as its done.
答案1
得分: 2
有很多方法可以做到这一点,所以没有具体的示例,你不会得到具体的答案。可能需要查看 CompletableFuture,它有许多方法来定义后续工作、组合工作、拆分工作等。
Future<String> f = CompletableFuture.supplyAsync(() -> "INITIAL WORK")
.thenApply(String::toLowerCase) // 进行更多工作
.thenAccept(queue::add); // 将结果放入队列,某些东西正在从中读取
f.join();
// 批处理完成
英文:
There are many ways do this so, without a concrete example, you won't get a concrete answer. Likely want to look at CompletableFuture which has many methods for defining follow-on work, combining work, splitting work etc.
Future<String> f = CompletableFuture.supplyAsync(() -> "INITIAL WORK")
.thenApply(String::toLowerCase) // Do some more work
.thenAccept(queue::add); // put results onto a queue something is reading from
f.join();
// Batch complete
答案2
得分: 1
希望您正在使用Java 8或更高版本。
每当您提到“一旦未来的任务完成”,您想要使用CompletableFuture
及其.thenApply()
方法,正如@drekbour建议的那样。
然后,您有多个线程以非确定性顺序运行不同的任务。但最后,您希望在单个(主)线程中获取所有结果。为了实现这一点,您可以使用CompletableFuture.allOf
方法,.join()
它 - 然后迭代所有(已完成的)未来结果而无需等待。
英文:
I hope you are using Java 8 or later version.
Whenever you mention "as soon as a future task is complete", you want to use CompletableFuture
and its .thenApply()
method, as @drekbour suggests.
Then you have multiple threads running different tasks in non-determenistic sequence. But at the end you want to get all the results in the single (Main) thread. To achieve it, you can use CompletableFuture.allOf
method, .join()
it - and then iterate over all the (already completed) future results without waiting.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论