Coroutines nos bastidores

No artigo anterior entendemos o que são Coroutines e qual problema elas se propõe a resolver. Nesse segundo artigo da...

Data de publicação: 20/10/2018

No artigo anterior entendemos o que são Coroutines e qual problema elas se propõe a resolver. Nesse segundo artigo da série sobre Coroutines, vamos entender melhor como elas funcionam “under the hood”.
Coroutines vs Threads
Conceitualmente, threads e Coroutines são iguais. No entanto, Coroutines são conhecidas como light-weight threads, o que significa na prática que elas são mais leves, ocupam menos memória e como resultado, nós podemos ter muito mais coroutines simultâneas do que threads.
Para entender melhor o conceito e qual o problema que estamos tentando resolver, vamos pensar no seguinte cenário: imagine que você vai desenvolver um sistema que recebe uma requisição, lê o arquivo local, faz o upload desse arquivo e retorna a url para acessar esse arquivo. Se tentássemos mostrar graficamente como ficaria essa aplicação rodando em modo single thread, ficaria algo como a imagem abaixo, onde verde seria o tempo em que a thread está trabalhando e o amarelo a thread aguardando. A thread inicia o processo, aguarda que o arquivo seja lido e retornado para a aplicação, depois inicia o upload do arquivo para o storage, aguarda novamente que o processo se conclua e então retorna a url.

Em teoria isso funcionaria, o problema é que no caso de uma segunda requisição chegar enquanto a primeira requisição está sendo processada, não seria possível processa-la enquanto a primeira não fosse concluída. Uma possível solução seria criar uma thread para cada requisição. Novamente isso poderia funcionar, no entanto threads podem ter um custo alto para sua aplicação e geralmente os recursos disponíveis são reduzidos, portanto devemos tentar usá-los da forma mais eficiente possível.

E se nós utilizássemos esse tempo que a thread está aguardando, para processar novas requisições? Nós teríamos um cenários mais ou menos assim:



Nesse caso, ao invés de ficar apenas aguardando, o processamento é quebrado em pequenos chunks e sempre que uma função (sub-rotina) for necessitar esperar algum resultado, ela avisa que a thread está disponível e outra sub-rotina que esteja na fila é executada. Assim que a outra requisição tem o resultado necessário para continuar seu processamento (arquivo foi lido, ou upload foi concluído por exemplo), ela entra na fila e continua de onde parou. Dessa forma temos nossa thread sendo usada de forma ativa por muito mais tempo, utilizando os recursos disponíveis de forma mais eficiente.
Algo interessante nesse modelo, é que as próprias funções controlam o fluxo, disponibilizam a thread e continuam depois de onde pararam, sem a intervenção de um SO. Esse tipo de processamento é conhecido como non-preemptive multi-tasking e é isto que as Coroutines se propõe a fazer. Usar os recursos de forma eficiente e multi-tarefas colaborativa e além disso permitem que o desenvolvedor escreva código sequencial e a linguagem faz o trabalho pesado nos bastidores para que o código assíncrono funcione sem que o desenvolvedor precise escrever nenhuma callback ou algo do tipo. Lembrando que esse conceito não é algo específico das Coroutines do Kotlin, o conceito já é antigo e foi aplicado nessa funcionalidade do Kotlin.
Existem alguns benchmarks que comprovam que as Coroutines são de fato mais leves que as threads comuns, mas para mostrar de forma prática, a documentação de Coroutines no github (https://github.com/Kotlin/kotlinx.coroutines), mostra um código que tenta criar 100.000 execuções simultâneas em background. Com Coroutines o código consegue rodar tranquilamente, enquanto com threads, muito provavelmente você terá uma exceção de Out of Memory.
Então é assim que uma Coroutine funciona para trabalhar processos assíncronos. No próximo artigo, vamos entender como as Coroutines no Kotlin aplicam esse conceito na prática, como o seu código escrito de forma assíncrona é executado? Descubra no próximo artigo da série! Até mais!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

um × quatro =

Posts relacionados

  1. Sobre a Dextra

    Somos especialistas em desenvolvimento de software sob medida para negócios digitais. Pioneiros na adoção de metodologias de gestão ágil, combinamos processos de design, UX, novas tecnologias e visão de negócio, desenvolvendo soluções que criam oportunidades para nossos clientes.

  2. Categorias

Scroll to top