Могу ли я заменить ReentrantLock и условие на CountDownLatch? - PullRequest
0 голосов
/ 01 июля 2019

Я работаю с устаревшей библиотекой, которая в качестве примера предоставляет приведенный ниже пример.Насколько я понимаю, вы предоставляете объект обратного вызова, и методы будут вызываться после того, как библиотека получит ответ.Я должен дождаться ответа и затем продолжить выполнение.В одном из методов обратного вызова я анализирую ответ и добавляю элементы в коллекцию (я сомневаюсь, что это должна быть синхронизированная коллекция, авторы только упоминают это: «onFailure может вызываться одновременно несколькими потоками, поэтому убедитесь, чточтобы правильно синхронизировать код вашего обратного вызова ")

private static List<MktDataPrice> requestMarket(XYZConnector xyzConnector, MktDataPerimeter perimeter) {

        final List<MktDataPrice> result = new Vector<MktDataPrice>();

        final ReentrantLock reentrantLock = new ReentrantLock();
        final Condition finishCondition = reentrantLock.newCondition();
        final AtomicBoolean finished = new AtomicBoolean(false);

        xyzConnector.request(new MktDataRequest(perimeter, today, yesterday), new MktDataCallback() {

            public void onFinish(String perimeterId) {
                LOGGER.info("On finish request ");
                try {
                    reentrantLock.lock();
                    finished.set(true);
                    finishCondition.signalAll();
                } finally {
                    reentrantLock.unlock();
                }
            }

            public void onFailure(String perimeterId, Throwable t) {
                LOGGER.error("On failure request market", t);
            }

            public void onBegin(String perimeterId) {
                LOGGER.info("On begin request market");
            }

            public void onData(String perimeterId, MktDataInfo data) {
               result.addAll(processData(data));  

            }
        });
        try {
            reentrantLock.lock();
            while (!finished.get()) {
                try {
                    finishCondition.await();
                } catch (InterruptedException e) {
                    LOGGER.error("Interrupted", e);
                }
            }
        } finally {
            reentrantLock.unlock();
        }

     return result;
    }

Я пытаюсь написать что-то более чистое, могу ли я заменить его на CountDownLatch, как в примере ниже, или я что-то упустил?Есть ли более чистый способ реализовать это?

 public List<MktDataPrice> requestReply(MktDataRequest perimeter) {

        final CountDownLatch latch = new CountDownLatch(1);
        List<MarketDataPrice> results = new ArrayList<>();

        MktDataCallback callback = new MktDataCallback() {

        @Override
        public void onData(String perimeter, MktDataInfo sgibML_marketDataInfo) {
            results.addAll(getMktDataPriceFromSgibml(mktDataInfo));
        }

        @Override
        public void onBegin(String perimeter) {
        }

        @Override
        public void onFinish(String perimeter) {
            latch.countDown();
        }

        @Override
        public void onFailure(String perimeter, Throwable throwable) {
            latch.countDown();
        }
    };


    xyzConnector.request(perimeter, callback);

    try {
        latch.await();
    } catch (InterruptedException ex) {
        log.error("Could not wait to get response.." , ex);
    }

    return results;
}
...