Simultaneidade estruturada e Coroutines

João Victor
Android Dev BR
Published in
4 min readFeb 18, 2022

Hoje vamos falar um pouco de algumas features muito pouco comentadas no nosso dia a dia com a biblioteca Coroutines.

Antes de começarmos, aconselho que, se você ainda não teve contato com a biblioteca utilizada, recomendo que revise antes de iniciar esta leitura.

Kotlin Coroutines

https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-supervisor-job.html

https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/index.html

Mas então, antes de começar, gostaria de falar um pouco mais sobre alguns pontos do Kotlin Coroutines

Decomposição paralela

Programas paralelos são projetados especificamente para tirar proveito de várias CPUs para resolver problemas de computação intensiva.

Os principais objetivos de desempenho são normalmente taxa de transferência e escalabilidade, o número de cálculos que podem ser executados por unidade de tempo e o potencial de melhoria, quando recursos computacionais adicionais estão disponíveis.

No entanto, estes são muitas vezes entrelaçados com outros objetivos de desempenho. Por exemplo, o paralelismo também pode melhorar as latências de resposta para um serviço que transfere o trabalho para uma instalação de execução paralela.

Jobs e Suspend Functions

Jobs e funções suspend podem ser considerados como quentes, pois eles são executados imediatamente após serem iniciados/invocados. Mas, os Jobs iniciará uma nova co-rotina, enquanto as funções irá suspender a linha atual. Vamos ver alguns exemplos ?

Hot Jobs

Como podemos ver na imagem acima, o código executou o printLn antes mesmo de finalizar o Job, e sim, esse é o esperado de uma co-rotina.

Mas e se gostaríamos que houvesse um Job estruturado? Como por exemplo, não executar um código abaixo antes de finalizar nosso Job. Oque deveríamos fazer?

A função join, suspenderá o código até que o "job" finalize, muito parecida com runBlockin.

Podemos também aguardar mais de um Job sequencialmente

Suspend fun and Structured Concorrency

Todas as co-rotinas iniciadas em uma função suspensa precisam ser interrompidas quando a função é retornada, você provavelmente precisará garantir que essas co-rotinas terminem antes do retorno.

Caso precisarmos rodar serviços em paralelo para obter performance, teríamos um problema com simultaneidade no código, onde a próxima linha de código seria lida antes mesmos das funções em paralelas finalizar.

Com a função suspensa coroutineScope, conseguimos obter simultaneidade mesmo em decomposições paralelas. Assim, a co-rotina aguarda todas co-rotinas filhas até que finalizem.

https://gist.github.com/jaozinfs/d1973aa76fa0d9f1b7b981adc7d983b3

Caso aconteça algum erro em alguma das co-rotinas filhas do escopo, o mesmo falhará e o restante de seus filhos serão cancelados também.

Caso deseje um comportamento diferente, onde os outros filhos não sejam impactados por uma co-rotina que falhar, podemos utilizar supervisorScope

Com simultaneidade estruturada em Kotlin, você pode definir um coroutineScope que inicie uma ou mais corrotinas. Em seguida, usando await() (para uma corrotina única) ou awaitAll() (para diversas corrotinas), você pode garantir que essas corrotinas terminem antes de retornar da função.

Recomendo que continuem a leitura com os links a seguir.

E no proximo papo, falaremos sobre Yield

--

--