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] 
  • Oyente dentro del productor
  • cómo limitar kotlin coroutines máxima concurrency
  • ¿Cuál es la diferencia entre CoroutineContext y Job en kotlinx.coroutines?
  • reference no resuelta: lanzamiento
  • ¿Hay alguna forma de get el comportamiento de FixedTreadPool usando corutinas?
  • Fan-out / fan-in - canal de resultado de cierre
  • Multithreading usando Kotlin Coroutines
  • ¿Hay alguna forma de reutilizar una instancia de Job?
  • Qué significa cerrar un canal de kotlinx.coroutines
  • Cuál es la diferencia entre launch / join y async / await en Kotlin coroutines
  • cómo implementar una llamada limitada con retrofit que bloquea el cliente y corutinas