gpt4 book ai didi

java - 如何从多个线程中获取第一个结果并取消剩余

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:38:30 25 4
gpt4 key购买 nike

我有请求和多个线程,它们以不同的方式寻找结果,每个线程应该在某个时候得到一些结果。我需要接受< strong>第一个完成的线程的结果,返回这个结果并杀死所有剩余的线程。当我返回一些默认结果时,我也会超时。

我能想到两个解决方案,但对我来说没有一个是“正确的”..

1) 循环遍历任务,询问它们是否完成, hibernate 一会儿并返回它找到的第一个完成的任务..

import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.apache.log4j.LogManager;

public class App {
public static final ExecutorService executors = Executors.newCachedThreadPool();

public static void main(String[] args) {
ArrayList<Future<String>> taskList = new ArrayList<>();
taskList.add(executors.submit(new Task1()));
taskList.add(executors.submit(new Task2()));

String result = null;
long start = System.currentTimeMillis();
long timeout = 1000;

while ((start + timeout) < System.currentTimeMillis()) {
try {
for (Future<String> future : taskList) {
if (future.isDone()) {
result = future.get();
break;
}
}

if (result != null) {
break;
}

Thread.sleep(10);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}

if (result == null) {
result = "default..";
}
}

}

class Task1 implements Callable<String> {
@Override
public String call() throws Exception {
// find result in one way
return new String("result..");
}
}

class Task2 implements Callable<String> {
@Override
public String call() throws Exception {
// find result in some other way
return new String("result..");
}
}

2) 通过调用 future.get(timeout, TimeUnit.MILLISECONDS); 用另一个线程监视每个任务,然后第一个完成的线程将调用 future.cancel(true); 用于所有其他线程...

第一个解决方案在我看来像是在浪费处理器时间,而在我看来第二个解决方案在我看来像是在浪费线程......

最后,问题是:有没有更好的解决方案?

提前致谢

编辑:谢谢大家的回答,我已经使用“John H”的回答解决了这个问题:

There is a built in function that does this: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#invokeAny%28java.util.Collection,%20long,%20java.util.concurrent.TimeUnit%29

This will invoke all the tasks you give it, and wait for the first one to return an answer up to a time limit. If none of them return a result in time you can catch the TimeoutException and return the default value. Otherwise you can use the first value it returns and it will take care of cancelling the rest of the tasks.

最佳答案

有一个内置函数可以执行此操作:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#invokeAny%28java.util.Collection,%20long,%20java.util.concurrent.TimeUnit%29

这将调用您给它的所有任务,并等待第一个任务在一定时间内返回答案。如果它们都没有及时返回结果,您可以捕获 TimeoutException 并返回默认值。否则,您可以使用它返回的第一个值,它将负责取消其余任务。

关于java - 如何从多个线程中获取第一个结果并取消剩余,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37482098/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com