1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
import kotlinx.coroutines.* import kotlin.concurrent.thread class Counter { private var count = 0 fun increment() { synchronized(this) { println("esperar...") count++ } } fun getCount(): Int { synchronized(this) { return count } } } fun main() { val counter = Counter() thread { for (i in 1..100) { Thread.sleep(10) counter.increment() } } runBlocking { withContext(Dispatchers.IO) { for (i in 1..100) { delay(10) counter.increment() println("Count: ${counter.getCount()}") } } } } |
Explicación línea a línea:
1 2 |
import kotlinx.coroutines.* import kotlin.concurrent.thread |
En esta sección se importan las bibliotecas necesarias. kotlinx.coroutines
es la biblioteca que proporciona soporte para la programación asíncrona en Kotlin utilizando corrutinas. kotlin.concurrent.thread
es una biblioteca estándar de Kotlin que permite crear hilos para ejecutar tareas de forma concurrente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Counter { private var count = 0 fun increment() { synchronized(this) { count++ } } fun getCount(): Int { synchronized(this) { return count } } } |
Aquí se define la clase Counter
, que tiene un contador privado llamado count
. Los métodos increment
y getCount
están sincronizados utilizando synchronized(this)
para asegurar el acceso seguro al contador desde hilos múltiples. El método increment
incrementa el contador en uno, mientras que el método getCount
devuelve el valor actual del contador.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
fun main() { val counter = Counter() thread { for (i in 1..100) { Thread.sleep(10) counter.increment() } } runBlocking { withContext(Dispatchers.IO) { for (i in 1..100) { delay(10) println("Count: ${counter.getCount()}") } } } } |
En la función main
, se crea una instancia de la clase Counter
llamada counter
. A continuación, se crea un hilo adicional utilizando thread
para ejecutar un bucle que incrementa el contador en uno y espera 10 milisegundos entre cada incremento.
Dentro de runBlocking
, se utiliza withContext(Dispatchers.IO)
para crear un contexto en el que se ejecutará el siguiente bloque de código de manera asíncrona en el hilo de E/S. Esto es necesario para evitar bloquear el hilo principal mientras se accede al contador.
Dentro de withContext
, se ejecuta otro bucle que muestra el valor actual del contador utilizando counter.getCount()
y lo imprime en la consola. También se introduce un retraso de 10 milisegundos entre cada iteración del bucle.
En resumen, este código crea un contador sincronizado que puede ser accedido de forma segura por hilos múltiples. Muestra cómo el acceso sincronizado puede ralentizar la ejecución del programa al detener brevemente la ejecución en cada acceso al contador sincronizado.