如何使用 Java 中的执行器执行 returns 个不同对象的方法
How to execute methods which returns different objects using Executors in Java
我有 4 种方法 return 不同的列表 类。让我们说
public List<A> getA(String param1, String param2){
//some code here
}
public List<B> getB(String param1, String param2){
//some code here
}
public List<C> getC(String param1, String param2){
//some code here
}
public List<D> getD(String param1, String param2){
//some code here
}
我想同时执行这4个方法,我在下面使用Callable和Executor
Callable<List<A>> collableA = new Callable<List<A>>() {
@Override
public List<A> call() throws Exception {
return getA();
}
};
Callable<List<B>> collableB = new Callable<List<B>>() {
@Override
public List<B> call() throws Exception {
return getB();
}
};
Callable<List<D>> collableD = new Callable<List<D>>() {
@Override
public List<D> call() throws Exception {
return getD();
}
};
Callable<List<C>> collableC = new Callable<List<C>>() {
@Override
public List<C> call() throws Exception {
return getC();
}
};
// add to a list
List<Callable> taskList = new ArrayList<Callable>();
taskList.add(collableA );
taskList.add(collableB);
taskList.add(collableC);
taskList.add(collableD);
//create a pool executor with 4 threads
ExecutorService executor = Executors.newFixedThreadPool(4);
Future<List<FrozenFrameAlert>> futureFrozen = executor.submit(taskList);
// getting error here submit() not accepting taskList
我尝试使用 InvokeAll()
和 invokeAny()
方法,但没有方法接受此 taskList
我找到了解决方案,您只需要使用通用接口 Callable<T>
而不是 Callable
来让 ExecutorService#invokeAll(Collection<? extends Callable<T>> tasks)
方法接受 List<Callable<T>>
.
示例:
List<Callable<List<?>>> taskList = new ArrayList<>();
taskList.add(() -> new ArrayList<>(Arrays.asList(1,2,3)));
taskList.add(() -> new ArrayList<>(Arrays.asList("a","b","c")));
ExecutorService executor = Executors.newFixedThreadPool(4);
List<Future<List<?>>> futureList = executor.invokeAll(taskList);
for (Future<List<?>> future : futureList) {
System.out.println(future.get());
}
如果你真的有不同的 return 类型,你仍然需要使用 Callable<T>
和一些合适的类型,比如超级接口或至少 Object
。
错误是说你的
List<Callable> taskList = new ArrayList<Callable>();
不是通用的,应该类似于 。
List<Callable<List>> taskList = new ArrayList<>();
只需对每个可调用对象使用 submit()
;这将为您提供四个期货,每个期货都有正确的类型:
Future<List<A>> futureA = executor.submit(callableA);
Future<List<B>> futureB = executor.submit(callableB);
etc.
如果您在继续之前需要所有四个期货的结果,您可以依次阻止每个期货:
List<A> resultA = futureA.get();
List<B> resultB = futureB.get();
etc.
要做一些更一般化的事情,您需要找出一种方式让所有这些列表 "the same"。但是,如果您不以相同的方式使用它们,那么它们是不同的类型并不重要。
我有 4 种方法 return 不同的列表 类。让我们说
public List<A> getA(String param1, String param2){
//some code here
}
public List<B> getB(String param1, String param2){
//some code here
}
public List<C> getC(String param1, String param2){
//some code here
}
public List<D> getD(String param1, String param2){
//some code here
}
我想同时执行这4个方法,我在下面使用Callable和Executor
Callable<List<A>> collableA = new Callable<List<A>>() {
@Override
public List<A> call() throws Exception {
return getA();
}
};
Callable<List<B>> collableB = new Callable<List<B>>() {
@Override
public List<B> call() throws Exception {
return getB();
}
};
Callable<List<D>> collableD = new Callable<List<D>>() {
@Override
public List<D> call() throws Exception {
return getD();
}
};
Callable<List<C>> collableC = new Callable<List<C>>() {
@Override
public List<C> call() throws Exception {
return getC();
}
};
// add to a list
List<Callable> taskList = new ArrayList<Callable>();
taskList.add(collableA );
taskList.add(collableB);
taskList.add(collableC);
taskList.add(collableD);
//create a pool executor with 4 threads
ExecutorService executor = Executors.newFixedThreadPool(4);
Future<List<FrozenFrameAlert>> futureFrozen = executor.submit(taskList);
// getting error here submit() not accepting taskList
我尝试使用 InvokeAll()
和 invokeAny()
方法,但没有方法接受此 taskList
我找到了解决方案,您只需要使用通用接口 Callable<T>
而不是 Callable
来让 ExecutorService#invokeAll(Collection<? extends Callable<T>> tasks)
方法接受 List<Callable<T>>
.
示例:
List<Callable<List<?>>> taskList = new ArrayList<>();
taskList.add(() -> new ArrayList<>(Arrays.asList(1,2,3)));
taskList.add(() -> new ArrayList<>(Arrays.asList("a","b","c")));
ExecutorService executor = Executors.newFixedThreadPool(4);
List<Future<List<?>>> futureList = executor.invokeAll(taskList);
for (Future<List<?>> future : futureList) {
System.out.println(future.get());
}
如果你真的有不同的 return 类型,你仍然需要使用 Callable<T>
和一些合适的类型,比如超级接口或至少 Object
。
错误是说你的
List<Callable> taskList = new ArrayList<Callable>();
不是通用的,应该类似于 。
List<Callable<List>> taskList = new ArrayList<>();
只需对每个可调用对象使用 submit()
;这将为您提供四个期货,每个期货都有正确的类型:
Future<List<A>> futureA = executor.submit(callableA);
Future<List<B>> futureB = executor.submit(callableB);
etc.
如果您在继续之前需要所有四个期货的结果,您可以依次阻止每个期货:
List<A> resultA = futureA.get();
List<B> resultB = futureB.get();
etc.
要做一些更一般化的事情,您需要找出一种方式让所有这些列表 "the same"。但是,如果您不以相同的方式使用它们,那么它们是不同的类型并不重要。