2017-10-10 34 views
1

Java具有ThreadLocal變量,對於運行並行操作而不踩其他線程或循環分配,例如OpenCV使用videoCapture.retrieve(image),「image」可以是線程變量。kotlin中的「協同本地」變量

Kotlin是否有任何「協同本地」變量的含義?如果我想以他們的反例爲例,但是每個協程都有一個計數器,我該怎麼做?

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

我想你可以使用'CoroutineContext':https://kotlinlang.org/api/latest/jvm/stdlib/ kotlin.coroutines.experimental/-coroutine上下文/ – marstran

回答

2

如果您正在尋找ThreadLocal作爲一個性能優化,確保每個線程得到它的一些臨時對象的自己的副本,那麼你應該繼續使用ThreadLocal用於這一目的。可能會有比線程更多的協程,並且爲每個協程保留一些臨時對象的副本可能會造成更多的傷害而不是好處。

如果您正在尋找ThreadLocal,以此來繞過方法調用的一些背景,那麼我強烈建議考慮明確地傳遞這種情況下進入你的功能,或者使用一些依賴注入框架來做到這一點。

如果你有一個罕見的情況下,你確實需要通過周圍的一些方面,但由於某些技術原因,你不能明確地傳遞它也可以使用DI(也就是你會使用ThreadLocal與線程),你可以與協程一起使用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 
} 

您可以使用+運營商等背景元素結合您的問題(見"Combining Contexts" in the guide瞭解詳細信息)

從您的協同代碼中,您始終可以從coroutineContext中檢索您的元素。所有標準構建者將CoroutineScope實例納入其範圍,這使得其coroutineContext屬性可用。如果您深入調用堆棧的暫停函數,那麼您可以定義自己的幫助器函數來檢索當前上下文,直到它在未來更新之一中進入標準庫爲止。詳情請參閱KT-17609

在手的coroutineScope,很容易找回你的元素:

val myElement = coroutineScope[MyContextElement]