我有一个接口,用于搜索由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是所有子系统的相同对象,因此我需要一个系统,该系统可以立即开始所有搜索并将其结果放入结果对象。
我希望可以几乎同步地填充那些对象,从而使用户不必等待所有系统完成。
最好的问候 丹尼尔
答案 0 :(得分:0)
如果您愿意使用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);
}