簡體   English   中英

Kotlin中的“協程局部”變量

[英]“coroutine local” variables in kotlin

Java具有ThreadLocal變量,非常適合運行並行操作,而無需踩踏其他線程或按循環分配,例如OpenCV使用videoCapture.retrieve(image) ,而“ image”可以是線程videoCapture.retrieve(image)變量。

Kotlin是否具有“協程局部”變量的含義? 如果我想以他們的反例為例,但每個協程都有一個計數器,我該怎么做?

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

如果您正在尋找ThreadLocal作為性能優化,以確保每個線程都獲得自己的某個臨時對象的副本,則應繼續為此目的使用ThreadLocal 協程可能比線程更多,並且為每個協程保留一些臨時對象的副本可能弊大於利。

如果您正在尋找ThreadLocal作為在方法調用周圍傳遞某些上下文的方法,那么我強烈建議考慮將此上下文顯式傳遞給您的函數或使用某種依賴注入框架來實現。

如果在極少數情況下確實需要傳遞一些上下文,但是由於某種技術原因,您不能顯式傳遞它,也不能使用DI(也就是將ThreadLocal與線程一起使用的CoroutineContext ),則可以將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]

對於如今在這個問題上絆腳石的人來說,似乎語法已經有所更改:

class MyContextElement : AbstractCoroutineContextElement(MyContextElement), CoroutineContext.Element {
    override val key = Key

    companion object Key : CoroutineContext.Key<KCallScope>

}

為了成為CoroutineContext.Key您現在需要實現CoroutineContext.Element ,這需要您實現key

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM