@@ -81,9 +81,11 @@ public interface ThreadContextElement<S> : CoroutineContext.Element {
81
81
* Wraps [ThreadLocal] into [ThreadContextElement]. The resulting [ThreadContextElement]
82
82
* maintains the given [value] of the given [ThreadLocal] for coroutine regardless of the actual thread its is resumed on.
83
83
* By default [ThreadLocal.get] is used as a value for the thread-local variable, but it can be overridden with [value] parameter.
84
+ * Beware that context element **does not track** modifications of the thread-local and accessing thread-local from coroutine
85
+ * without the corresponding context element returns **undefined** value. See the examples for a detailed description.
84
86
*
85
- * Example usage looks like this:
86
87
*
88
+ * Example usage:
87
89
* ```
88
90
* val myThreadLocal = ThreadLocal<String?>()
89
91
* ...
@@ -97,7 +99,7 @@ public interface ThreadContextElement<S> : CoroutineContext.Element {
97
99
* println(myThreadLocal.get()) // Prints "null"
98
100
* ```
99
101
*
100
- * Note that the context element does not track modifications of the thread-local variable, for example:
102
+ * The context element does not track modifications of the thread-local variable, for example:
101
103
*
102
104
* ```
103
105
* myThreadLocal.set("main")
@@ -109,12 +111,27 @@ public interface ThreadContextElement<S> : CoroutineContext.Element {
109
111
* ```
110
112
*
111
113
* Use `withContext` to update the corresponding thread-local variable to a different value, for example:
112
- *
113
114
* ```
114
115
* withContext(myThreadLocal.asContextElement("foo")) {
115
116
* println(myThreadLocal.get()) // Prints "foo"
116
117
* }
117
118
* ```
119
+ *
120
+ * Accessing the thread-local without corresponding context element leads to undefined value:
121
+ * ```
122
+ * val tl = ThreadLocal.withInitial { "initial" }
123
+ *
124
+ * runBlocking {
125
+ * println(tl.get()) // Will print "initial"
126
+ * // Change context
127
+ * withContext(tl.asContextElement("modified")) {
128
+ * println(tl.get()) // Will print "modified"
129
+ * }
130
+ * // Context is changed again
131
+ * println(tl.get()) // <- WARN: can print either "modified" or "initial"
132
+ * }
133
+ * ```
134
+ * to fix this behaviour use `runBlocking(tl.asContextElement())`
118
135
*/
119
136
public fun <T > ThreadLocal<T>.asContextElement (value : T = get()): ThreadContextElement <T > =
120
137
ThreadLocalElement (value, this )
0 commit comments