Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Multithreading calculation in steps


Автор: gelo86 17.11.2012, 16:16
Добрый день. Всю суть рассказать не могу (секрет фирмы). У меня есть список Account'ов. Мне надо с каждым Account'ом сделать три шага:
1. Подсчитать определенные коэффициенты.
2. Вычислить окончательные суммы.
3. Сгенерировать каждому PDF документ.
Все три шага одному Account'у должны идти в описанной последовательности (последующий шаг использует результат предыдущего шага, который сохраняется  в базе данных).

Использую thread pool ( Executors.newFixedThreadPool ) Код выглядит примерно так:
Код

ExecutorService executor = Executors.newFixedThreadPool(...);
for (Acccount account : accounts) {
    executor.submit(new Precalculate(account));
}
executor.shutwodn();
executor.awaitTermination(...)

executor = Executors.newFixedThreadPool(...);
for (Acccount account : accounts) {
    PreCalulationResult result = preCalculationResultDAO.find(account);
    executor.submit(new Calculate(account, result));
}
executor.shutwodn();
executor.awaitTermination(...)

...
for (Acccount account : accounts) {
    CalulationResult result = calculationResultDAO.find(account);
    executor.submit(generatePdf(account, result));
}
...


Так запуская каждый шаг, я знаю, что в базе данных уже будет результат предыдущего шага.
Клиент требует, чтобы была возможность запускать каждый шаг отдельно (если вдруг надо будет руками подрегулировать какие-то данные определенного шага), но в большинстве случаев будут запускаться все три.

Вопрос в том, как можно сделать (если запускаются все три шага) чтобы следующий шаг брал данные не из базы данных но прямо от предыдущего шага, т.е. как сделать, чтобы например executor.submit(new Calculate(account)); вызывался не из цикла, а по завершению например Future<PreCalulationResult>preResultFuture =   executor.submit(new Precalculate(account));.

Побывал добавлять preResultFuture в ArrayList  и каждому в цикле вызывать get(), но проблема в том, что тогда очень большое количество объектов хроняться в heap'е (memory leak na 1GB). Да и получаеться много if'ов, запускать / не запускать шаг, брать из базы данных или ждать результат от другого Runnable/Future.

Может есть решения для таких ситуаций /  design patter ? 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)