как заставить основной поток ждать завершения потоков службы исполнителя - PullRequest
1 голос
/ 07 мая 2020

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

 line 1- missingStrategyContext.process(FileType.CARD, programId, fromDate, toDate, channel);
 line 2- missingStrategyContext.process(FileType.TRANSACTION, programId, fromDate, toDate, channel);
 line 3- missingStrategyContext.process(FileType.REFUND, programId, fromDate, toDate, channel);

 line 4- processingLog.setProcessingStatus(TransactionState.SUCCESS.name());

Внутри каждого процесса я выбираю значение типа файла, какую стратегию мне нужно вызвать

public void process(FileType fileType, String programId, Long fromDate, Long toDate, String channel){
    map.get(fileType).process(programId, fromDate, toDate, channel, fileType);
}

, а затем, в зависимости от типа файла, я реализовал свой метод процесса и вызвал службу исполнителя в каждой реализации типа файла

@Override
public void process(String programId, Long fromDate, Long toDate, String channel, FileType fileType) {

    MultiTenantTxMgmt multiTenantTxMgmt = MultiTenantTxMgmtUtil.get(programId);
    EntityManager entityManager = null;

    List<MissingReason> reasonList = new ArrayList<>();
    try {
        entityManager = multiTenantTxMgmt.getEntityManager();
        reasonList = missingDataRepository.getDistinctMissingReasonForFileType(entityManager, fileType, TransactionState.READYTOATTEMPT);
    }catch (Exception exception) {
        logger.error(exception.getMessage(), exception);
        throw new UnkownBatchSaveException();
    } finally {
        entityManager.close();
    }

    reasonList.forEach(
            missingReason -> deExecutorService.dotask(() ->
                    missingTransactionStrategyContext.processMissingV3(missingReason, programId, fromDate, toDate, channel, fileType)
            )
    );

}

Ответы [ 2 ]

2 голосов
/ 07 мая 2020

Вы можете использовать CountDownLatch#await. Например, скопировано из документов:

CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);

for (int i = 0; i < N; ++i) // create and start threads
    new Thread(new Worker(startSignal, doneSignal)).start();

doSomethingElse();            // don't let run yet
startSignal.countDown();      // let all threads proceed
doSomethingElse();
doneSignal.await();           // wait for all to finish
0 голосов
/ 07 мая 2020

Вы можете сделать doTask метод, позволяющий возвращать (завершаемое) будущее (если это еще не сделано) и возвращать список фьючерсов в методе process, например, заменить

reasonList.forEach(
            missingReason -> deExecutorService.dotask(() ->
                    missingTransactionStrategyContext.processMissingV3(missingReason, programId, fromDate, toDate, channel, fileType)
            )
    );

на

    final List<Future> futures = reasonList.stream()
        .map(missingReason -> deExecutorService.dotask(() ->
            missingTransactionStrategyContext
                .processMissingV3(missingReason, programId, fromDate, toDate, channel, fileType)))
        .collect(Collectors.toList());

  }
return futures;

Затем в вызывающей части вы можете дождаться завершения всех этих фьючерсов, прежде чем продолжить.

...