O que são corotinas em Kotlin?

O que são corotinas em Kotlin?


Coroutines são ótimos recursos disponíveis no idioma Kotlin. Eu já tentei e realmente gostei.


O objetivo deste artigo é ajudar você a entender Corutins. Apenas tenha cuidado ao ler e você terá sucesso.


Vamos começar com a definição oficial de Corutin.


As corotinas são uma nova maneira de escrever código assíncrono e sem bloqueio.

A primeira pergunta que surge ao ler esta definição é como as corotinas são diferentes dos fluxos?


As corotinas são fluxos leves. Um encadeamento leve significa que ele não está vinculado ao encadeamento nativo; portanto, não requer mudança de contexto para o processador; portanto, é mais rápido.


O que significa "não anexado ao encadeamento nativo" ?


As corotinas são encontradas em muitas linguagens de programação.


Basicamente, existem dois tipos de Corutin:


  • usando a pilha;
  • pilha não utilizada;

O Kotlin implementa Coroutines sem uma pilha - isso significa que as Coroutines não têm sua própria pilha e, portanto, não estão vinculadas ao encadeamento nativo.


Coroutines e fluxos são multitarefa. Mas a diferença é que os threads são controlados pelo sistema operacional e as Coroutines são pelos usuários.


Agora você pode ler e entender conscientemente o trecho do site oficial da Kotlin:


As corotinas podem ser representadas na forma de um fluxo facilitado. Como os threads, as corotinas podem trabalhar em paralelo, esperar um pelo outro e se comunicar. A maior diferença é que as corotinas são muito baratas, quase gratuitas: podemos criá-las aos milhares e pagar muito pouco em termos de desempenho. Os fluxos são caros. Milhares de threads podem ser um problema sério, mesmo para uma máquina moderna.

Vamos ver como trabalhar com Coroutines


Então, como iniciar a rotina (semelhante a iniciar um thread)?


Existem duas funções para iniciar corotinas:


  • launch{}
  • async{}

iniciar {} vs async {} nas Kotlin Coroutines


A diferença é que o launch{} não retorna nada e o async{} retorna uma instância Deferred que possui uma função wait await() que retorna o resultado de uma rotina, exatamente como Future in Java, onde fazemos future.get() para obter o resultado .


Vamos dar uma olhada no uso do launch {}


 fun main(args: Array<String>) { println("Kotlin Start") launch(CommonPool) { delay(2000) println("Kotlin Inside") } println("Kotlin End") } 

 // The output will be // Kotlin Start // Kotlin End // Kotlin Inside 

Esse código iniciará uma nova corotina nesse pool de threads. Nesse caso, usamos o CommonPool , que usa ForkJoinPool.commonPool () . Os fluxos ainda existem em um programa baseado em corotina, mas um encadeamento pode executar muitas corotinas, portanto, não há necessidade de muitos encadeamentos.


Vamos tentar uma coisa:


 fun main(args: Array<String>) { delay(2000) } 

Se você fizer isso diretamente na função principal, receberá uma mensagem de erro:


As funções de interrupção só podem ser chamadas a partir de corotina ou outra função de interrupção.


A função de atraso é uma função de interrupção, portanto, podemos chamá-la apenas de uma corotina ou outra função de interrupção.


Vamos consertar isso:


 fun main(args: Array<String>) { runBlocking { delay(2000) } } 

Outro exemplo:


 suspend fun doWorkFor1Seconds(): String { delay(1000) return "doWorkFor1Seconds" } 

 suspend fun doWorkFor2Seconds(): String { delay(2000) return "doWorkFor2Seconds" } 

 // Serial execution private fun doWorksInSeries() { launch(CommonPool) { val one = doWorkFor1Seconds() val two = doWorkFor2Seconds() println("Kotlin One : " + one) println("Kotlin Two : " + two) } } 

 // The output is // Kotlin One : doWorkFor1Seconds // Kotlin Two : doWorkFor2Seconds 

Agora, vamos usar o async {}


 // Parallel execution private fun doWorksInParallel() { val one = async(CommonPool) { doWorkFor1Seconds() } val two = async(CommonPool) { doWorkFor2Seconds() } launch(CommonPool) { val combined = one.await() + "_" + two.await() println("Kotlin Combined : " + combined) } } // The output is // Kotlin Combined : doWorkFor1Seconds_doWorkFor2Seconds 

Porque async{} usamos async{} , podemos ligar para await() para obter o resultado.


Feliz aprendizado;)

Source: https://habr.com/ru/post/pt421473/


All Articles