Variables "coroutine local" en kotlin

Java tiene variables ThreadLocal que son agradables para ejecutar operaciones paralelas sin pisar otros hilos o asignaciones por bucle, por ejemplo, OpenCV usa videoCapture.retrieve(image) , y "image" podría ser una variable threadcal.

¿Kotlin tiene algún sentido de las variables "coroutine-local"? Si quisiera tomar su ejemplo de contador pero tengo un contador por coroutine, ¿cómo lo haría?

 for (i in 1..1_000_000) thread(start = true) { c.addAndGet(i) } 

Si está buscando ThreadLocal como una optimization del performance, para asegurarse de que cada hilo obtenga su propia copy de algún object temporal, debe continuar utilizando ThreadLocal para tal fin. Puede haber muchas más corotinas que hilos, y save una copy de algún object temporal para cada corrutina puede hacer más daño que bien.

Si está buscando ThreadLocal como una forma de pasar algo de context acerca de la invocación de methods, entonces le sugiero que considere explícitamente pasar este context a sus funciones o usar algún marco de dependency injections para hacerlo.

Si tiene un caso raro en el que realmente necesita pasar algo de context, pero por alguna razón técnica no puede pasarlo explícitamente ni puede usar DI (que es donde habría utilizado ThreadLocal con hilos), puede usar CoroutineContext con corutinas . Los pasos son:

Define tu propia class de elemento de context coroutine usando la siguiente plantilla:

 class MyContextElement : AbstractCoroutineContextElement(MyContextElement) { companion object Key : CoroutineContext.Key<MyContextElement> // you state/code is here } 

Crea una instancia de tu elemento y pásala al creador de corotinas cuando comiences tu corutina. El siguiente ejemplo usa launch coroutine builder, pero funciona con todos ellos ( async , produce , actor , etc.)

 launch(MyContextElement()) { // the code of your coroutine } 

Puede combinar su context con otros elementos de context utilizando + operadores (consulte "Combinación de contexts" en la guía para get más detalles)

Desde el interior de su código de coroutine siempre puede recuperar su elemento del coroutineContext . Todos los constructores estándar incorporan la instancia de CoroutineScope en su scope, lo que hace que su propiedad coroutineContext esté disponible. Si está en lo más profundo de la stack de llamadas de funciones de suspensión, puede definir su propia function de ayuda coroutineContext() para recuperar el context actual hasta que coroutineContext() a la biblioteca estándar en una de las actualizaciones futuras. Ver KT-17609 para más detalles.

Con coroutineScope en mano, es fácil recuperar su elemento:

 val myElement = coroutineScope[MyContextElement] 
  • Kotlin coroutines y Spring Framework 5 types reactivos
  • ¿Hay alguna forma de reutilizar una instancia de Job?
  • Limpiar el uso de Coroutines en Kotlin con el soporte de testing unitaria
  • ¿Cuál es la diferencia entre CoroutineContext y Job en kotlinx.coroutines?
  • Corutinas de testing unitaria en el hilo de UI
  • ¿Cómo se ejecuta el método de suspensión a través de la reflexión?
  • Kotlin Process Collection En Paralelo?
  • ¿Cómo se organizan múltiples corrutines y bloques de expectativas en una testing de Kotlin Spek?
  • Multithreading usando Kotlin Coroutines
  • Qué significa cerrar un canal de kotlinx.coroutines
  • Kotlin Coroutines en un service de Android