kotlin中的“协同本地”变量

Java具有ThreadLocal变量,对于运行并行操作而言,不需要videoCapture.retrieve(image)其他线程或每循环分配,例如OpenCV使用videoCapture.retrieve(image) ,而“image”可以是threadlocal变量。

Kotlin是否具有“协同本地”变量的意义? 如果我想以他们的反例为例,但是每个协程都有一个计数器,那我该怎么做呢?

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

如果您正在寻找ThreadLocal作为性能优化,为了确保每个线程都获得一些临时对象的副本,那么您应该继续使用ThreadLocal 。 比线程可以有更多的协程,并且为每个协程保留一些临时对象的副本可能会造成更多的伤害。

如果你正在寻找ThreadLocal作为传递方法调用的方法,那么我强烈建议考虑明确地将这个上下文传递给你的函数,或者使用一些依赖注入框架来实现。

如果你确实需要传递一些上下文,但是由于某些技术原因,你不能明确地传递它,也不能使用DI(这就是你将ThreadLocal与线程一起使用的CoroutineContext ),你可以使用CoroutineContext和协程。 步骤是:

使用以下模板定义您自己的协同程序上下文元素类:

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

创建元素的实例,并在启动协程时将其传递给协程生成器。 以下示例使用launch协程生成器,但它适用于所有这些( asyncproduceactor等)

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

您可以使用+运算符将您的上下文与其他上下文元素相结合 (有关详细信息,请参阅指南中的“合并上下文” )

在你的协程代码中,你总是可以从coroutineContext获取你的元素。 所有标准构建者都将CoroutineScope实例带入其范围,这使得它的coroutineContext属性可用。 如果您深入调用堆栈的暂停函数,那么您可以定义自己的coroutineContext()辅助函数来检索当前上下文,直到它在未来更新之一中进入标准库为止。 详情请参阅KT-17609 。

通过使用coroutineScope ,可以轻松地检索元素:

 val myElement = coroutineScope[MyContextElement]