Java - дождитесь завершения Lambda, прежде чем продолжить

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

for(String data : dataArray) {
    APIEndpoint apiCall = new APIEndpoint("http://sampleAPI.org/route/" + data);
    apiCall.execute(((response, success) -> {
        //Format and gather the info from the response
        apiDataArray.add(DataFromAPIObject);
    }));
}
System.out.print(apiDataArray.size());//Returns 0
sortData();//Currently Doesn't Sort anything because the array is empty

Обновлено: вот исполнитель конечной точки, с которым я работаю: https://github.com/orange-alliance/TOA-DataSync/blob/master/src/org/theorangealliance/datasync/util/FIRSTEndpoint.java

Почему бы вам не переместить вызов sortData() в лямбда / обратный вызов?

k5_ 03.11.2018 23:51

Возвращает ли метод APIEndpoint.execute что-нибудь, например Будущее? Если это не так, вы всегда можете использовать apiDataArray.add(index, DataFromAPIObject), где index определяется с помощью Collections.binarySearch.

VGR 03.11.2018 23:51

Вам нужно создать Futures в вызове и дождаться их завершения вне цикла перед сортировкой.

Bohemian 03.11.2018 23:53

Используйте интерфейс обратного вызова или семафор

MadProgrammer 03.11.2018 23:55

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

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

Ответы 1

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

Возможно использование семафоров. Но он зайдет в тупик, если по какой-то причине не будет ответа хотя бы по одной из точек data. (Чтобы исправить тупик, вам может потребоваться освободить семафор при ошибках).

    Semaphore semaphore = new Semaphore(dataArray.length);
    for (String data : dataArray) { 
        semaphore.acquire();        
        APIEndpoint apiCall = new APIEndpoint("http://sampleAPI.org/route/" + data);
        apiCall.execute(((response, success) -> {
            // Format and gather the info from the response
            apiDataArray.add(DataFromAPIObject);
            semaphore.release();
        }));
    }
    semaphore.acquire(dataArray.length);
    sortData();

Это не сработало, семафор был получен, но после того, как семафор был получен, он не вошел в лямбду, и поэтому никогда не был выпущен

techno_11 04.11.2018 03:12

Вам необходимо зарегистрировать обработчик ошибок и освободить семафор при ошибках.

k5_ 04.11.2018 15:49

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