Jugando con Corrutinas en Kotlin

Overview

Kotlin Init Coroutines

Jugando con Corrutinas en Kotlin

Kotlin LISENCE GitHub

imagen

Acerca De

Distintos ejemplos de uso de Corrutinas y Concurrencia en Kotlin

Suspender vs Bloquear. Funciones de suspensión

En el contexto de concurrencia, bloquear un hilo significa que el hilo se mantendrá fuera de uso mientras éste encuentre algo que lo bloquee. Ésto podría ser la espera de la liberación de un recurso, una llamada a la función Thread.sleep, una llamada a un servicio externo, etc. Mientras se encuentre en ese estado, el hilo no podrá ser usado para realizar otras tareas. Por el contrario, suspender un hilo significa que el hilo estará libre y listo para ser usado en la ejecución de otras tareas mientras se encuentra a la espera de la liberación de un recurso, una llamada a la función delay, una llamada a un servicio externo, etc. La naturaleza de las coroutines es suspender la ejecución evitando a toda costa llamadas a funciones que bloquean. Ésta es la magia que le permite a las coroutines ser tan eficientes y de bajo consumo de recursos en comparación con los hilos regulares de siempre.

Las funciones de suspensión tienen la capacidad de suspender la ejecución de la corrutina mientras están haciendo su trabajo. Una vez que termina, el resultado de la operación se devuelve y se puede utilizar en la siguiente línea.

Contexto de corrutina

Contexto de corrutina El contexto de corrutina es un conjunto de reglas y configuraciones que definen cómo se ejecutará la corrutina. Por debajo, es una especie de Map, con un conjunto de claves y valores posibles.

Una de las posibles configuraciones es el dispatcher que se utiliza para identificar el hilo donde se ejecutará la corrutina. Este dispatcher se puede proporcionar de dos maneras:

  • Explícitamente: Configuramos manualmente el dispatcher que se utilizará.
  • Por el scope de la corrutina

Constructores de Corrutinas

Existen varios constructores de coroutines, cada uno para un caso específico. Estos constructores son: runBlocking, launch, async y produce. También es posible crear coroutines dentro de otra coroutine sin ninguna limitación. Por lo tanto, una coroutine puede tener muchas coroutines “hijas”, y éstas a su vez pueden tener más coroutines “hijas” y así infinitamente. Ejem02

runBlocking

Éste es un caso especial de constructor. Crea una coroutine y suspende el hilo que lo ejecuta hasta que la coroutine finalice, es decir, bloquea el hilo actual hasta que se terminen todas las tareas dentro de esa corrutina. Este constructor no debe ser usado nunca, excepto para hacer pruebas unitarias de nuestras suspend functions. También es posible usarlo en el método main para jugar con las coroutines tal y como lo estamos haciendo en este momento. NUNCA utilices este constructor de coroutines en código de producción. Debido a que runBlocking no es una función de extensión de la interfaz CoroutineScope, se puede usar en el interior de cualquier función.

Lo que en realidad pasa al crear una coroutine con runBlocking es que el hilo que la crea esperará a que la coroutine finalice para continuar con la ejecución en la línea que está inmediatamente después.

launch

Este constructor crea una coroutine devolviendo un objeto de tipo Job. Debido a que este constructor es una función de extensión de la interfaz CoroutineScope, se puede llamar solamente desde adentro de una coroutine o dentro de una suspend function. Se utiliza para hacer tareas que no requieren la devolución de ningún valor.

Como mencioné anteriormente, el constructor launch se puede llamar solamente desde adentro de una coroutine o dentro de una suspend function.

job.join

Con está función, puedes bloquear la corrutina asociada con el job hasta que todos los jobs hijos hayan finalizado.

job.cancel

Esta función cancelará todos sus jobs hijos asociados.

async

Este constructor crea una coroutine devolviendo un objeto de tipo Deferred siendo T el tipo de dato esperado. Por ejemplo Int, String, etc. Debido a que el constructor async es una función de extensión de la interfaz CoroutineScope, se puede llamar solamente desde adentro de una coroutine o dentro de una suspend function. Se utiliza para hacer tareas que requieren la devolución de algún valor. O por ejemplo poder lanzar dos cosas en paralelo. Permite ejecutar varias tareas en segundo plano en paralelo. No es una función de suspensión en sí misma, por lo que cuando ejecutamos async, el proceso en segundo plano se inicia, pero la siguiente línea se ejecuta de inmediato Este objeto tiene una nueva función llamada await() que es la que bloquea. Llamaremos a await() solo cuando necesitemos el resultado. Si el resultado aún no esta listo, la corrutina se suspende en ese punto. Si ya tenemos el resultado, simplemente lo devolverá y continuará. De esta manera, puedes ejecutar tantas tareas en segundo plano como necesites.

produce

Este constructor crea una coroutine que se utiliza para la comunicación por medio de canales (Channels) con otras coroutines

Dispatchers

Los dispatchers son un tipo de contextos de corrutina que especifican el hilo o hilos que pueden ser utilizados por la corrutina para ejecutar su código. Hay dispatchers que solo usan un hilo (como Main) y otros que definen un grupo de hilos que se optimizarán para ejecutar todas las corrutinas que reciben.

Si recuerdas, al principio dijimos que 1 hilo puede ejecutar muchas corrutinas, por lo que el sistema no creará 1 hilo por corrutina, sino que intentará reutilizar los que ya están vivos.

Tenemos cuatro dispatchers principales:

  • Default: Se usará cuando no se defina un dispatcher, pero también podemos configurarlo explícitamente. Este dispatcher se utiliza para ejecutar tareas que hacen un uso intensivo de la CPU, principalmente cálculos de la propia App, algoritmos, etc. Puede usar tantos subprocesos como cores tenga la CPU. Ya que estas son tareas intensivas, no tiene sentido tener más ejecuciones al mismo tiempo, porque la CPU estará ocupada.
  • IO: Utiliza este para ejecutar operaciones de entrada/salida. En general, todas las tareas que bloquearán el hilo mientras esperan la respuesta de otro sistema: peticiones al servidor, acceso a la base de datos, sitema de archivos, sensores… ya que no usan la CPU, se puede tener muchas en ejecución al mismo tiempo, p por lo que el tamaño de este grupo de hilos es de 64. Las Apps lo que más hacen, es interactuar con el dispositivo y hacer peticiones de red, por lo que probablemente usarás este la mayoría del tiempo.
  • Unconfined: Si no te importa mucho qué hilo se utiliza, puedes usar este dispatcher. Es difícil predecir qué hilo se usará, así que no lo uses a menos que estés muy seguro de lo que estás haciendo.
  • Main: Este es un dispatcher especial que se incluye en las librerías de corrutinas relacionadas con interfaz de usuario. En particular, en Android, utilizará el hilo de UI.

Secuencialidad vs Paralelismo

El orden de ejecución de cada sentencia en una coroutine es secuencial. Si queremos lanzar en hilos distintos y ademas coordinar la asincronia o paralelimiadad debemos usar async. Posteriomente, sincronizaremos con await. Ejem03

CourentineScope

Cada vez que usamos un constructor de coroutines en realidad estamos haciendo una llamada a una función que recibe como primer parámetro un objeto de tipo CoroutineContext. Los constructores launch y async son en realidad funciones de extensión de la interfaz CoroutineScope

Global scope

Es un scope general que se puede usar para cualquier corrutina que deba continuar con la ejecución mientras la aplicación se está ejecutando. Por lo tanto, no deben estar atados a ningún componente específico que pueda ser destruido. Crear una coroutine valiéndose del objeto GlobalScope, se asemeja a crear una coroutine con un Job no cancelable. Es decir, la coroutine romperá la relación con el Scope donde fue creada y vivirá hasta que la aplicación finalice su ejecución. Por esta razón su uso se desaconseja a tal punto que solo debe hacerse cuando sabes muy bien lo que estás haciendo.

Extra – Convertir callbacks a corrutinas

Existe una función llamada suspendCancellableCoroutine, que nos permite pasar de un mundo a otro:

suspend fun suspendAsyncLogin(username: String, password: String): User =
    suspendCancellableCoroutine { continuation ->
        userService.doLoginAsync(username, password) { user ->
            continuation.resume(user)
        }
    }

Esta función devuelve un objeto continuation que se puede utilizar para devolver el resultado del callback. Simplemente llame a continuation.resume y ese resultado será devuelto por la suspending function a la corrutina padre. ¡Es así fácil!

Autor

Codificado con 💖 por José Luis González Sánchez

Twitter GitHub

Contacto

Cualquier cosa que necesites házmelo saber por si puedo ayudarte 💬 .

        

Licencia

Este proyecto está licenciado bajo licencia MIT, si desea saber más, visite el fichero LICENSE para su uso docente y educativo.

Referencias

You might also like...
A Kotlin Native program to show the time since a date, using Kotlin LibUI
A Kotlin Native program to show the time since a date, using Kotlin LibUI

TimeSince A Kotlin Native program to show the time since a date, using Kotlin LibUI Report Bug . Request Feature About The Project TimeSince is a Kotl

RoomJetpackCompose is an app written in Kotlin and shows a simple solution to perform CRUD operations in the Room database using Kotlin Flow in clean architecture.
RoomJetpackCompose is an app written in Kotlin and shows a simple solution to perform CRUD operations in the Room database using Kotlin Flow in clean architecture.

RoomJetpackCompose is an app written in Kotlin and shows a simple solution to perform CRUD operations in the Room database using Kotlin Flow in clean architecture.

Create an application with Kotlin/JVM and Kotlin/JS, and explore features around code sharing, serialization, server- and client
Create an application with Kotlin/JVM and Kotlin/JS, and explore features around code sharing, serialization, server- and client

Practical Kotlin Multiplatform on the Web 본 저장소는 코틀린 멀티플랫폼 기반 웹 프로그래밍 워크숍(강좌)을 위해 작성된 템플릿 프로젝트가 있는 곳입니다. 워크숍 과정에서 코틀린 멀티플랫폼을 기반으로 프론트엔드(front-end)는 Ko

Create an application with Kotlin/JVM and Kotlin/JS, and explore features around code sharing, serialization, server- and client
Create an application with Kotlin/JVM and Kotlin/JS, and explore features around code sharing, serialization, server- and client

Building a Full Stack Web App with Kotlin Multiplatform 본 저장소는 INFCON 2022에서 코틀린 멀티플랫폼 기반 웹 프로그래밍 핸즈온랩을 위해 작성된 템플릿 프로젝트가 있는 곳입니다. 핸즈온 과정에서 코틀린 멀티플랫폼을

Kotlin library for Android
Kotlin library for Android

KAndroid Kotlin library for Android providing useful extensions to eliminate boilerplate code in Android SDK and focus on productivity. Download Downl

Type-safe time calculations in Kotlin, powered by generics.

Time This library is made for you if you have ever written something like this: val duration = 10 * 1000 to represent a duration of 10 seconds(in mill

📒 NotyKT is a complete 💎Kotlin-stack (Backend + Android) 📱 application built to demonstrate the use of Modern development tools with best practices implementation🦸.
📒 NotyKT is a complete 💎Kotlin-stack (Backend + Android) 📱 application built to demonstrate the use of Modern development tools with best practices implementation🦸.

NotyKT 🖊️ NotyKT is the complete Kotlin-stack note taking 🖊️ application 📱 built to demonstrate a use of Kotlin programming language in server-side

A Kotlin DSL wrapper around the mikepenz/MaterialDrawer library.
A Kotlin DSL wrapper around the mikepenz/MaterialDrawer library.

MaterialDrawerKt Create navigation drawers in your Activities and Fragments without having to write any XML, in pure Kotlin code, with access to all t

Kotlin-based modern RecyclerView rendering weapon
Kotlin-based modern RecyclerView rendering weapon

Read this in other languages: 中文, English, Changelog Yasha Item introduction: Kotlin-based modern RecyclerView rendering weapon Item Features: No Adap

Owner
José Luis González Sánchez
Dr. en Informática (PhD). Profe de Secundaria en DAM/DAW/ASIR. Soy GitHub Campus Advisor y Embajador de GitKraken. Tenis, rock, guitarra y buenos momentos.
José Luis González Sánchez
A somewhat copy past of Jetbrain's code from the kotlin plugin repo to make it humanly possible to test Intellij IDEA kotlin plugins that work on kotlin

A somewhat copy past of Jetbrain's code from the kotlin plugin repo to make it humanly possible to test Intellij IDEA kotlin plugins that work on kotlin

common sense OSS 0 Jan 20, 2022
Real life Kotlin Multiplatform project with an iOS application developed in Swift with SwiftUI, an Android application developed in Kotlin with Jetpack Compose and a backed in Kotlin hosted on AppEngine.

Conferences4Hall Real life Kotlin Multiplatform project with an iOS application developed in Swift with SwiftUI, an Android application developed in K

Gérard Paligot 98 Dec 15, 2022
Android + Kotlin + Github Actions + ktlint + Detekt + Gradle Kotlin DSL + buildSrc = ❤️

kotlin-android-template ?? A simple Github template that lets you create an Android/Kotlin project and be up and running in a few seconds. This templa

Nicola Corti 1.5k Jan 3, 2023
LifecycleMvp 1.2 0.0 Kotlin is MVP architecture implementation with Android Architecture Components and Kotlin language features

MinSDK 14+ Download Gradle Add to project level build.gradle allprojects { repositories { ... maven { url 'https://jitpack.io' }

Robert 20 Nov 9, 2021
Opinionated Redux-like implementation backed by Kotlin Coroutines and Kotlin Multiplatform Mobile

CoRed CoRed is Redux-like implementation that maintains the benefits of Redux's core idea without the boilerplate. No more action types, action creato

Kittinun Vantasin 28 Dec 10, 2022
👋 A common toolkit (utils) ⚒️ built to help you further reduce Kotlin boilerplate code and improve development efficiency. Do you think 'kotlin-stdlib' or 'android-ktx' is not sweet enough? You need this! 🍭

Toolkit [ ?? Work in progress ⛏ ?? ??️ ?? ] Snapshot version: repositories { maven("https://s01.oss.sonatype.org/content/repositories/snapshots") }

凛 35 Jul 23, 2022
An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile.

An app architecture for Kotlin/Native on Android/iOS. Use Kotlin Multiplatform Mobile. 项目架构主要分为原生系统层、Android/iOS业务SDK层、KMM SDK层、KMM业务逻辑SDK层、iOS sdkfra

libill 4 Nov 20, 2022
Provides Kotlin libs and some features for building Kotlin plugins

Kotlin Plugin Provides Kotlin libs and some features for building awesome Kotlin plugins. Can be used instead of CreeperFace's KotlinLib (don't use to

null 3 Dec 24, 2021
Notes-App-Kotlin - Notes App Built Using Kotlin

Notes-App-Kotlin Splash Screen Home Page Adding New Notes Filter Feature Search

Priyanka 4 Oct 2, 2022
Kotlin-client-dsl - A kotlin-based dsl project for a (Client) -> (Plugin) styled program

kotlin-client-dsl a kotlin-based dsl project for a (Client) -> (Plugin) styled p

jackson 3 Dec 10, 2022