gpt4 book ai didi

java - 运行具有单个超时的多个任务(线程)的最佳实践是什么(在所有线程中运行最多 30 秒)?

转载 作者:行者123 更新时间:2023-11-30 01:40:37 38 4
gpt4 key购买 nike

我想出了一个解决方案,但我想看看是否有人有更好的方法或更标准的方法来做到这一点。

主要方法演示了我将如何使用此类。在其生产版本中,我将保持线程池打开并继续重用它,而不是在调用后将其关闭。

public class MultiCallManager<T>
{

private ExecutorService service;
private Map<String, Future<T>> futureResults;
private Map<String, T> results;
private Map<String, Exception> errors;

public MultiCallManager(ExecutorService inService)
{
service = inService;
futureResults = new LinkedHashMap<String, Future<T>>();
results = new LinkedHashMap<String, T>();
errors = new LinkedHashMap<String, Exception>();
}

public void add(String key, Callable<T> task)
{
Future<T> result = service.submit(task);
futureResults.put(key, result);
}

public boolean hasErrors()
{
return !errors.isEmpty();
}

public T getResult(String key)
{
return results.get(key);
}

public Exception getException(String key)
{
return errors.get(key);
}

public void waitUntilDone(long timeout)
{
for (Entry<String, Future<T>> entry : futureResults.entrySet())
{
if (timeout < 0)
{
timeout = 0;
}
long start = System.currentTimeMillis();
try
{
results.put(entry.getKey(), entry.getValue().get(timeout, TimeUnit.MILLISECONDS));
}
catch (Exception e)
{
errors.put(entry.getKey(), e);
}
long end = System.currentTimeMillis();
long time = end - start;
timeout = timeout - time;
}
}

public static void main(String[] args) throws Exception
{
ExecutorService service = Executors.newFixedThreadPool(5);

MultiCallManager sandbox = new MultiCallManager(service);

final String value = "AWESOME!";

Callable<Object> c1 = new Callable<Object>()
{

@Override
public String call() throws Exception
{
Thread.sleep(5000);
return value;
}
};

Callable<Object> c2 = new Callable<Object>()
{

@Override
public Object call() throws Exception
{
Thread.sleep(6000);
return value;
}
};

Callable<Object> c3 = new Callable<Object>()
{

@Override
public Object call() throws Exception
{
Thread.sleep(2000);
return value;
}
};

sandbox.add("c1", c1);
sandbox.add("c2", c2);
sandbox.add("c3", c3);
sandbox.waitUntilDone(5000);

if (sandbox.getResult("c1") != null)
{
System.out.println(sandbox.getResult("c1"));
}
else
{
sandbox.getException("c1").printStackTrace();
}
if (sandbox.getResult("c2") != null)
{
System.out.println(sandbox.getResult("c2"));
}
else
{
sandbox.getException("c2").printStackTrace();
}
if (sandbox.getResult("c3") != null)
{
System.out.println(sandbox.getResult("c3"));
}
else
{
sandbox.getException("c3").printStackTrace();
}
service.shutdownNow();
}

}

最佳答案

看看 CompletionService 和/或 CountDownLatch,它们可以用更好的代码完成您正在做的一些事情。

CompletionService 提供了类似于 BlockingQueue 的接口(interface),因此您可以使用poll(long timeout, TimeUnit unit)方法。每次轮询时,您都希望将超时设置为所有线程的剩余时间,并在时间到时退出。

这本质上取代了您的 waitUntilDone 方法,执行相同的工作。

关于java - 运行具有单个超时的多个任务(线程)的最佳实践是什么(在所有线程中运行最多 30 秒)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/340826/

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