¿Cómo sincronizar las corrutinas en Android?
sobes.tech AI
Respuesta de la IA
Para sincronizar corutinas en Android, se pueden usar varios enfoques, dependiendo de la tarea específica:
-
Join: Esperar a que otra corutina termine.
// Iniciar la primera corutina val job1 = CoroutineScope(Dispatchers.Default).launch { delay(1000) println("Trabajo 1 terminado") } // Iniciar la segunda corutina val job2 = CoroutineScope(Dispatchers.Default).launch { delay(500) println("Trabajo 2 terminado") } // Esperar a que ambas corutinas terminen job1.join() job2.join() println("Todos los trabajos terminados") -
Await: Esperar el resultado de una operación asíncrona representada por Deferred.
// Operación asíncrona que devuelve un resultado val deferredResult = CoroutineScope(Dispatchers.Default).async { delay(1000) "Resultado de async" } // Esperar el resultado val result = deferredResult.await() println(result) -
CoroutineScope.coroutineScope: Crear un nuevo ámbito de alcance que solo terminará después de que todas las corutinas hijas hayan finalizado. Útil para competencia estructurada.
suspend fun doParallelWork() { coroutineScope { // Crear un nuevo scope de competencia estructurada launch { delay(1000); println("Tarea 1 terminada") } launch { delay(500); println("Tarea 2 terminada") } } // Este punto solo se alcanzará después de que las tareas 1 y 2 hayan finalizado println("Todas las tareas paralelas terminadas") } -
Semántica de actores (Channel): Para intercambio de mensajes y sincronización de acceso a datos modificables entre corutinas.
// Crear un canal para intercambiar Int val channel = Channel<Int>() CoroutineScope(Dispatchers.Default).launch { // Enviar datos al canal for (i in 1..5) { channel.send(i) } channel.close() // Cerrar el canal después de enviar } CoroutineScope(Dispatchers.Default).launch { // Recibir datos del canal for (value in channel) { println("Recibido $value") } } -
Mutex: Para garantizar acceso exclusivo a un recurso compartido.
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock val mutex = Mutex() var counter = 0 suspend fun incrementCounter() { mutex.withLock { // Adquirir el mutex counter++ // El mutex se liberará automáticamente al salir del bloque } }
La elección del método depende de qué exactamente se necesita sincronizar: esperar a que termine, obtener un resultado, gestionar tareas paralelas, intercambiar datos o acceso exclusivo. coroutineScope es el enfoque recomendado por defecto para competencia estructurada.