kotlin中的“协同本地”变量
Java具有ThreadLocal变量,对于运行并行操作而不踩其他线程或循环分配,例如OpenCV使用videoCapture.retrieve(image)
,“image”可以是线程变量。kotlin中的“协同本地”变量
Kotlin是否有任何“协同本地”变量的含义?如果我想以他们的反例为例,但是每个协程都有一个计数器,我该怎么做?
for (i in 1..1_000_000)
thread(start = true) {
c.addAndGet(i)
}
如果您正在寻找ThreadLocal
作为一个性能优化,确保每个线程得到它的一些临时对象的自己的副本,那么你应该继续使用ThreadLocal
用于这一目的。可能会有比线程更多的协程,并且为每个协程保留一些临时对象的副本可能会造成更多的伤害而不是好处。
如果您正在寻找ThreadLocal
,以此来绕过方法调用的一些背景,那么我强烈建议考虑明确地传递这种情况下进入你的功能,或者使用一些依赖注入框架来做到这一点。
如果你有一个罕见的情况下,你确实需要通过周围的一些方面,但由于某些技术原因,你不能明确地传递它也可以使用DI(也就是你会使用ThreadLocal
与线程),你可以与协程一起使用CoroutineContext
。步骤如下:
使用以下模板定义自己的协同程序上下文元素类:
class MyContextElement : AbstractCoroutineContextElement(MyContextElement) {
companion object Key : CoroutineContext.Key<MyContextElement>
// you state/code is here
}
创建元素的一个实例,并把它传递给当您启动协程的协同程序生成器。下面的示例使用launch
协同程序制造商,但它与所有这些(async
,produce
,actor
等)的作品
launch(MyContextElement()) {
// the code of your coroutine
}
您可以使用+
运营商等背景元素结合您的问题(见"Combining Contexts" in the guide了解详细信息)
从您的协同代码中,您始终可以从coroutineContext
中检索您的元素。所有标准构建者将CoroutineScope实例纳入其范围,这使得其coroutineContext
属性可用。如果您深入调用堆栈的暂停函数,那么您可以定义自己的帮助器函数来检索当前上下文,直到它在未来更新之一中进入标准库为止。详情请参阅KT-17609。
在手的coroutineScope
,很容易找回你的元素:
val myElement = coroutineScope[MyContextElement]
我想你可以使用'CoroutineContext':https://kotlinlang.org/api/latest/jvm/stdlib/ kotlin.coroutines.experimental/-coroutine上下文/ – marstran