Проблема многопоточности -> получение результата потока после его завершения

Вот мой код:

List<Object> array= new ArrayList<Object>();
         int i=0;
         ExecutorService pool = Executors.newFixedThreadPool(50);   
         for(String str : strList) {

             LittleDwarfWorker littleDwarfWorker = new LittleDwarfWorker(params including a datasource);

                try {
                    pool.execute(littleDwarfWorker);
                }catch(Exception e) {
                    e.printStackTrace();
                }
                finally{
                     i++;
                    array.add(littleDwarfWorker.getResult());
                    if ((i%100)==0) {
                        log.info("Progression :"+i+"/"+listeEan.size());
                    }
                }       
         }
         pool.shutdown();

Вот мой любимый гномик:

    public void run() {
        JdbcTemplate localJdbcTemplate = new JdbcTemplate(this.dataSource);
        //dwarf dig in database to find some diamonds
    }

Моя проблема в том, что когда я бегу, array пусто. Я предполагаю, что мой код плохо отформатирован, но мне недостаточно удобно работать с многопоточностью, чтобы найти свою ошибку. Я предполагаю, что инструкция array.add() выполняется до того, как мой поток закончит свою работу, поэтому значение пусто.

Что я ищу: каждый поток получает своего собственного рабочего, когда у рабочего есть результат, он добавляет результат в мой массив. Для меня finally будет выполняться ПОСЛЕ того, как мой поток получит информацию из БД.

Я посмотрел здесь метод отправки Возвращаемое значение из потока, но я не уверен, как получить «будущее» значение. Потому что, если мой метод запуска не пуст, я получаю сообщение об ошибке.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

ExecutorService в java так не работает. Я предполагаю, что вы LittleDwarfWorker implmenets Runnable и что getResult() — ваше творение. Чтобы сделать это Java, как вам нужно вашему работнику implements Callable<Object>, что позволяет вам напрямую получить результат после завершения задачи. Вам также понадобится CompletionService. Таким образом, вы сначала отправляете все задачи, а затем собираете их результат. .take() возвращает Future<V>, который содержит ваш результат, поэтому он будет блокироваться, пока не будет готов.

ExecutorService executor = Executors.newFixedThreadPool(50);    
CompletionService<Obejct> completionService = new ExecutorCompletionService<> (executor);
for(String str : strList) {
    completionService.submit(new LittleDwarfWorker(...));
}

for ( int i = 0; i < strList.size(); i++ ) {
  try {
    Object result = completionService.take().get();
    // ... do whatever something with the object

  } catch ( InterruptedException | ExecutionException e ) {
    e.printStackTrace();
  }
}

executor.shutdown();

@Westanger спасибо за объяснение, по крайней мере, я понимаю, почему мой подход был плохим. Благодаря вам мое время выполнения сократилось с 2 часов 30 минут до 8 минут!

Azrael_404 09.04.2019 16:41

Другие вопросы по теме