Kotlin runBlocking и asyn c с возвратом - PullRequest
1 голос
/ 23 марта 2020

Я делаю первые шаги в kotlin сопрограммах, и у меня возникает проблема.

Чтобы создать Foo и вернуть его из функции, мне нужно асинхронно вызвать два тяжелых метода обслуживания, чтобы получить некоторые значения для Foo создания. Это мой код:

   return runBlocking {
        val xAsync = async {
            service.calculateX()
        }
        val yAsync = async {
            service.calculateY()
        }
        Foo(xAsync.await(), yAsync.await())
    };

Однако после чтения логов мне кажется, что calculateX() и calculateY() вызываются синхронно. Мой код правильный?

1 Ответ

1 голос
/ 24 марта 2020

Ваш код не идеален, но он верен с точки зрения обеспечения одновременной работы calculateX() и calculateY(). Однако, поскольку он запускает эту параллельную работу с диспетчером runBlocking, который является однопоточным, и поскольку ваши тяжелые операции блокируют, а не приостанавливают, они не будут распараллелены.

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

Второе замечание - вы можете по крайней мере заставить их работать параллельно, каждая блокировка свой собственный поток с помощью диспетчера ввода-вывода:

return runBlocking {
    val xAsync = async(Dispatchers.IO) {
        service.calculateX()
    }
    val yAsync = async(Dispatchers.IO) {
        service.calculateY()
    }
    Foo(xAsync.await(), yAsync.await())
};

По сравнению с использованием java.util.concurrent API, здесь вы получаете выгоду от диспетчера ввода-вывода библиотеки вместо необходимости создавать собственный пул потоков.

...