Весеннее параллельное выполнение метода

1

Я в ситуации, когда у меня есть коллекция объектов, и каждый объект должен запускать дорогой метод, который занимает около 5-10 секунд.

Как я могу запускать все методы параллельно и периодически проверять статус?

Я попытался использовать аннотацию @Async с ответом " Будущее", но ничего не изменилось.

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);

}

Есть ли способ ThreadPoolTaskExecutor?

Теги:
spring
spring-mvc
multitasking

1 ответ

2
Лучший ответ

Я немного смущен относительно причин, по которым вы используете AsyncResult (и какая реализация... ejb?). Если я не ошибаюсь, это не будет работать так, как (из того, что я знаю) AsyncResult связан с bean-компонентом и @Asyncronous аннотацией, что делает ответ от конкретного метода bean assyncronous. Но если использовать внутри объекта, это будет эффективно последовательным.

Здесь вам нужно нормальное будущее. Если это так, вам нужно фактически запустить эти фьючерсы в исполнителе, а затем подождать, пока они закончат, вызывая future.get(). Хороший учебник по этому вопросу вы можете найти здесь: http://java.dzone.com/articles/javautilconcurrentfuture

Вы также можете посмотреть на Акку. Модель актера - мой личный фаворит, так как вы можете просто создать кучу работников, рассказать им, что делать, и позволить им сообщать вам, как только они закончили свою работу. Тем не менее это может быть излишним, если у вас есть простая задача под рукой, зависит от вашего стиля.

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. Что-то похожее на это: дождитесь, пока все потоки закончат свою работу в java

Ещё вопросы

Сообщество Overcoder
Наверх
Меню