提交 ec524b34 编写于 作者: oldratlee's avatar oldratlee 🔥

rename class name of CoroutineThreadLocalAsContextElement Test/Demo

上级 17550211
......@@ -5,7 +5,7 @@ private val threadLocal = ThreadLocal<String?>() // declare thread-local variabl
/**
* [Thread-local data - Coroutine Context and Dispatchers - Kotlin Programming Language](https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html#thread-local-data)
*/
fun main() = runBlocking<Unit> {
fun main() = runBlocking {
threadLocal.set("main")
println("Pre-main, current thread: ${Thread.currentThread()}, thread local value: ${threadLocal.get()}")
......
......@@ -4,14 +4,15 @@ import kotlinx.coroutines.*
import org.junit.Assert.*
import org.junit.Test
class CoroutineThreadLocalAsContextElementTest {
class CoroutineThreadContextElementTest {
@Test
fun oneThreadContextElement(): Unit = runBlocking {
fun threadContextElement_passByValue(): Unit = runBlocking {
val mainValue = "main-${System.currentTimeMillis()}"
val launchValue = "launch-${System.currentTimeMillis()}"
val testThread = Thread.currentThread()
val threadLocal = ThreadLocal<String?>() // declare thread-local variable
// String ThreadLocal, String is immutable value, can only be passed by value
val threadLocal = ThreadLocal<String?>()
threadLocal.set(mainValue)
println("test thread: ${Thread.currentThread()}, thread local value: ${threadLocal.get()}")
......@@ -44,6 +45,45 @@ class CoroutineThreadLocalAsContextElementTest {
assertEquals(mainValue, threadLocal.get())
}
@Test
fun threadContextElement_passByReference(): Unit = runBlocking {
data class Reference(var data: Int = 42)
val mainValue = Reference()
val launchValue = Reference(4242)
val testThread = Thread.currentThread()
// Reference ThreadLocal, mutable value, pass by reference
val threadLocal = ThreadLocal<Reference>() // declare thread-local variable
threadLocal.set(mainValue)
println("test thread: ${Thread.currentThread()}, thread local value: ${threadLocal.get()}")
val job = launch(Dispatchers.Default + threadLocal.asContextElement(value = launchValue)) {
println("Launch start, current thread: ${Thread.currentThread()}, thread local value: ${threadLocal.get()}")
assertEquals(launchValue, threadLocal.get())
assertNotEquals(testThread, Thread.currentThread())
delay(5)
println("After delay, current thread: ${Thread.currentThread()}, thread local value: ${threadLocal.get()}")
assertEquals(launchValue, threadLocal.get())
assertNotEquals(testThread, Thread.currentThread())
val reset = -42
threadLocal.get().data = reset
delay(5)
println("After delay set reset, current thread: ${Thread.currentThread()}, thread local value: ${threadLocal.get()}")
assertEquals(Reference(reset), threadLocal.get())
assertNotEquals(testThread, Thread.currentThread())
}
job.join()
println("after launch, test thread: ${Thread.currentThread()}, thread local value: ${threadLocal.get()}")
assertEquals(mainValue, threadLocal.get())
}
@Test
fun twoThreadContextElement(): Unit = runBlocking {
val mainValue = "main-a-${System.currentTimeMillis()}"
......
......@@ -24,7 +24,7 @@ fun main(): Unit = runBlocking {
println("Hello ${await()}!")
}
async(MyContext(myThreadLocal.get(), Dispatchers.IO)) {
async(MyThreadLocalContextContinuationInterceptor(myThreadLocal.get(), Dispatchers.IO)) {
"world(${myThreadLocal.get().data})"
}.run {
println("Hello ${await()}!")
......@@ -37,7 +37,7 @@ private val myThreadLocal = object : ThreadLocal<MyData>() {
}
}
private class MyContext(
private class MyThreadLocalContextContinuationInterceptor(
private var myData: MyData,
private val dispatcher: ContinuationInterceptor
) : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册