gpt4 book ai didi

java - 启动多个线程并收集结果

转载 作者:行者123 更新时间:2023-11-30 12:05:04 26 4
gpt4 key购买 nike

我有一个接口(interface),用于在 ENUM 收集的某些子系统中进行搜索。界面如下所示:

public interface ReferenceController {

public Map<String, ReferenceElement> searchElements(String searchField, List<String> searchItems, SystemStage systemStage) throws Exception;

public Boolean isAvailable(SystemStage systemStage) throws Exception;

public Boolean isAvailable(SystemStage systemStage) throws Exception;
}

ENUM 看起来像这样

public enum ReferenceSystem implements ReferenceController{
UCMDB (UcmdbFunctions.class),
PROIPS (ProIPSFunctions.class),
KV (KvFunctions.class),
FISERVICE(FiServiceFunctions.class),
COMMAND (CommandFunctions.class),
FII (FiiFunctions.class);

private Class<? extends ReferenceController> clazz;

private ReferenceSystem(Class<? extends ReferenceController> controllerClass) {
this.clazz = controllerClass;
}

public String displayName() {
return displayName(Locale.GERMAN);
}

public String displayName(Locale locale) {
ResourceBundle bundle = ResourceBundle.getBundle("EnumI18n", locale);
return bundle.getString(toString());
}

public Class<? extends ReferenceController> getClassname() { return clazz; }

@Override
public Map<String, ReferenceElement> searchElements(String searchField, List<String> searchItems, SystemStage systemStage) throws Exception {
Map<String, ReferenceElement> result = clazz.newInstance().searchElements(searchField, searchItems, systemStage);
return result;
}

@Override
public String getStateMapping(String value) {
try {
return clazz.newInstance().getStateMapping(value);
} catch (IllegalAccessException | InstantiationException e) {
return null;
}
}

@Override
public Boolean isAvailable(SystemStage systemStage) throws Exception {
return clazz.newInstance().isAvailable(systemStage);
}
}

此刻我开始一个接一个的搜索。所以我的服务器必须等待搜索完成才能开始下一个搜索。因此,用户必须等待很长时间才能显示结果。这段代码开始搜索

    public static void performSingleSearch(ReferenceSystem referenceSystem, String searchField, List<String> searchValues, SystemStage systemStage) throws Exception {

if(!isAvailable(referenceSystem, systemStage)) return;
Map<String, ReferenceElement> result = new HashMap<>();
try {
result = referenceSystem.searchElements(searchField, searchValues, systemStage);
} catch (Exception e) {
return;
}
if(result != null) orderResults(result, referenceSystem);
}

resultmap 是所有子系统的同一个对象,所以我需要一个所有搜索都立即开始并能够将其结果放入结果对象的系统。

我希望可以几乎同步地填充这些对象,这样用户就不必等待所有系统完成。

最好的问候丹尼尔

最佳答案

如果你愿意用Guava你可以使用 ListeningExecutorService.submit提交一个 Callable 包装每个对 searchElements 的调用并收集返回的 ListenableFuture列表中的实例。使用Futures.allAsList如果所有 future 都成功完成,则该列表可以转换为返回所有结果列表的 future ,否则返回所有结果的列表。

例如:

<T> void submitAll(
Collection<Callable<T>> callables,
Consumer<List<T>> onSuccess,
Consumer<Throwable> onError,
ExecutorService executor) {

ListeningExecutorService decoratedExecutor = MoreExecutors.listeningDecorator(executor);

List<ListenableFuture<T>> futures = Lists.newArrayList();
for (Callable<T> callable : callables) {
futures.add(decoratedExecutor.submit(callable));
}

FutureCallback<? super List<T>> cb = new FutureCallback<List<T>>() {
public void onSuccess(List<T> result) {
onSuccess.accept(result);
}

public void onFailure(Throwable t) {
onError.accept(t);
}
};

Futures.addCallback(Futures.allAsList(futures), cb, executor);
}

关于java - 启动多个线程并收集结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56634136/

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