如何使用Java中的Executors执行返回不同对象的方法

时间:2017-12-22 07:02:26

标签: java executorservice

我有4个方法返回不同类的List。让我们说

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

3 个答案:

答案 0 :(得分:1)

我找到了解决方案,您只需要使用通用接口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());
}

如果你真的有不同的返回类型,你仍然需要使用Callable<T>一些合适的类型,比如超级界面或至少Object

答案 1 :(得分:1)

为每个可调用对象使用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.

要做一些更通用的事情,你需要弄清楚所有这些列表“相同”的方式。但是,如果不以相同的方式使用它们,那么它们的类型不同并不重要。

答案 2 :(得分:0)

错误是说你的

List<Callable> taskList = new ArrayList<Callable>();

不是通用的应该是某些东西。

List<Callable<List>> taskList = new ArrayList<>();