Spring并行执行方法


问题内容

我遇到的情况是我有一个对象集合,每个对象都必须运行昂贵的方法,该方法大约需要5到10秒才能完成。

如何并行运行所有方法并定期检查状态?

我尝试将 @Async 批注与 Future 响应一起使用,但未进行任何更改。

public static void populate(String marketId) {
    //irrelevant code removed

    List<Company> companies = mongo().find(new Query(c), Company.class);
    List<Future> futures = new ArrayList<Future>();

    for(Company comp : companies) {
        futures.add(comp.updateData(market));
    }
}

@Async
public Future<Boolean> updateData(Market market) {
    //do my slow logic here

    return new AsyncResult(false);

}

ThreadPoolTask​​Executor
可行 的方式吗?


问题答案:

对于您使用AsyncResult的原因(以及哪个实现…
ejb?),我有些困惑。如果我没记错的话,它就不会那样工作,因为(据我所知)AsyncResult已连接到bean和@Asyncronous注释,从而使特定bean方法的响应异步。但是,如果在对象内部使用,它将是有效顺序的。

您这里需要的是正常的未来。如果是这样,则需要在执行程序中实际运行这些Future,然后等待调用future.get()直到它们完成。您可以在这里找到一个不错的教程:http
:
//java.dzone.com/articles/javautilconcurrentfuture

您也可以研究Akka。演员模型是我个人的最爱,因为您可以简单地产生一堆工人,告诉他们该怎么做,并让他们在完成工作后告诉您。如果您手头只有一个简单的任务,这仍然是一个矫over过正的选择,具体取决于您的风格。

ExecutorService pool = Executors.newFixedThreadPool(10);

public static void populate(String marketId) {
    //irrelevant code removed

    List<Company> companies = mongo().find(new Query(c), Company.class);
    List<Future> futures = new ArrayList<Future>();

    for(Company comp : companies) {
        futures.add(comp.updateData(market));
    }

    for(Future future: futures) {
        future.get()
    }
}

public Future<Boolean> updateData(Market market) {
  return pool.submit(new Callable<Boolean>() {
            @Override
            public Void call() throws Exception {
                //do your slow stuff here;
                return false;
            }
        })

}

当然,如果您需要从这些期货中获得一些实际回报,这很有意义。如果它们是无效的,并且您只需要一个线程在其他地方运行某些副作用,那么这样做就没有意义了,您可以简单地使用runnables和executor。