Проблема с одновременным выполнением метода в классе с различными параметрами, переданными через цикл с использованием ExecutorService - PullRequest
0 голосов
/ 06 мая 2019

Я пытаюсь написать программу для обработки операции с большим количеством сотрудников, около одного миллиона.Я использую ExecutorService для распараллеливания операции по созданию потоков в цикле сотрудников с размером пула 1000. (У меня 24-ядерный процессор (48 логических ядер) Intel с процессором 128 ГБ ОЗУ).Моя операция включает в себя много обращений к базе данных, поэтому я использую пул потоков размером 1000.

Моя цель - обработать операцию на сотрудниках, в то время как основной поток должен дождаться, пока все остальные потоки завершат задания, а затем вернется срезультат процесса.Проблема в том, что основной поток возвращается после создания потоков немедленно.

Код сервлета:

public class EmployeeProcess extends HttpServlet {

protected void doGet(....) {
  employeeDAO.executePrepareReport();
}

}

второй класс:


public class EmployeeDAOImpl implements EmployeeDAO {

   public void executePrepareReport() {
    ExecutorService executorService = Executors.newFixedThreadPool(1000);
        // method reference introduced in Java 8
        for(Employee employee : comp.listOfEmp) {

            executorService.submit(new Runnable() {
                public void run() {
                    prepareEmpReport(employee);
                }
            });
        }
        executorService.shutdown();
        //executorService.awaitTermination();
    }

   @Override
   public void prepareEmpReport(Employee  employee) {

   // process employee report with database accesses

   }

}

Пожалуйста, предложите исправление в коде или альтернативный эффективный способ сделать это

1 Ответ

2 голосов
/ 06 мая 2019

Существуют разные подходы к решению этой проблемы.

Два распространенных подхода:

  • CountDownLatch
  • ExecutorService.invokeAll

Вы можете использовать CountDownLatch:

Средство синхронизации, позволяющее одному или нескольким потокам ожидать завершения набора операций, выполняемых в других потоках.


Вы можете использовать метод invokeAll из ExecutorService:

Выполняет заданные задачи, возвращая список Futuresудерживая их статус и результаты, когда все завершено.Future.isDone () имеет значение true для каждого элемента возвращаемого списка.Обратите внимание, что завершенная задача могла быть завершена либо нормально, либо с помощью исключения.Результаты этого метода не определены, если данная коллекция была изменена во время выполнения этой операции.

...