@@ -4,14 +4,15 @@ import kotlinx.coroutines.*
4
4
import org.junit.Assert.*
5
5
import org.junit.Test
6
6
7
- class CoroutineThreadLocalAsContextElementTest {
7
+ class CoroutineThreadContextElementTest {
8
8
@Test
9
- fun oneThreadContextElement (): Unit = runBlocking {
9
+ fun threadContextElement_passByValue (): Unit = runBlocking {
10
10
val mainValue = " main-${System .currentTimeMillis()} "
11
11
val launchValue = " launch-${System .currentTimeMillis()} "
12
12
val testThread = Thread .currentThread()
13
13
14
- val threadLocal = ThreadLocal <String ?>() // declare thread-local variable
14
+ // String ThreadLocal, String is immutable value, can only be passed by value
15
+ val threadLocal = ThreadLocal <String ?>()
15
16
threadLocal.set(mainValue)
16
17
println (" test thread: ${Thread .currentThread()} , thread local value: ${threadLocal.get()} " )
17
18
@@ -44,6 +45,45 @@ class CoroutineThreadLocalAsContextElementTest {
44
45
assertEquals(mainValue, threadLocal.get())
45
46
}
46
47
48
+ @Test
49
+ fun threadContextElement_passByReference (): Unit = runBlocking {
50
+ data class Reference (var data : Int = 42 )
51
+
52
+ val mainValue = Reference ()
53
+ val launchValue = Reference (4242 )
54
+ val testThread = Thread .currentThread()
55
+
56
+ // Reference ThreadLocal, mutable value, pass by reference
57
+ val threadLocal = ThreadLocal <Reference >() // declare thread-local variable
58
+ threadLocal.set(mainValue)
59
+ println (" test thread: ${Thread .currentThread()} , thread local value: ${threadLocal.get()} " )
60
+
61
+ val job = launch(Dispatchers .Default + threadLocal.asContextElement(value = launchValue)) {
62
+ println (" Launch start, current thread: ${Thread .currentThread()} , thread local value: ${threadLocal.get()} " )
63
+ assertEquals(launchValue, threadLocal.get())
64
+ assertNotEquals(testThread, Thread .currentThread())
65
+
66
+ delay(5 )
67
+
68
+ println (" After delay, current thread: ${Thread .currentThread()} , thread local value: ${threadLocal.get()} " )
69
+ assertEquals(launchValue, threadLocal.get())
70
+ assertNotEquals(testThread, Thread .currentThread())
71
+
72
+ val reset = - 42
73
+ threadLocal.get().data = reset
74
+
75
+ delay(5 )
76
+
77
+ println (" After delay set reset, current thread: ${Thread .currentThread()} , thread local value: ${threadLocal.get()} " )
78
+ assertEquals(Reference (reset), threadLocal.get())
79
+ assertNotEquals(testThread, Thread .currentThread())
80
+ }
81
+ job.join()
82
+
83
+ println (" after launch, test thread: ${Thread .currentThread()} , thread local value: ${threadLocal.get()} " )
84
+ assertEquals(mainValue, threadLocal.get())
85
+ }
86
+
47
87
@Test
48
88
fun twoThreadContextElement (): Unit = runBlocking {
49
89
val mainValue = " main-a-${System .currentTimeMillis()} "
0 commit comments