bogdoll
04/03/2019, 6:00 PMclass ThreadlocalDelegate<E>(initializer: ()->E) {
private val threadLocal = ThreadLocal.withInitial(initializer)
operator fun getValue(thisRef: Any?, property: KProperty<*>): E {
return threadLocal.get()
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: E) {
threadLocal.set(value)
}
}
fun <E> threadlocal(initializer: ()->E) = ThreadlocalDelegate(initializer)
fun main() {
val sdf by threadlocal { SimpleDateFormat("yyyy-MM-dd HH:mm:ss").apply {
timeZone = TimeZone.getTimeZone("UTC")
}}
for(i in 0 until 10 ) {
thread {
println("${Thread.currentThread().name} - ${System.identityHashCode(sdf)}) - ${sdf.format(Date())}")
}
}
}
karelpeeters
04/03/2019, 6:11 PMCzar
04/03/2019, 6:12 PML1
L2
L3
karelpeeters
04/03/2019, 6:13 PMCzar
04/03/2019, 6:19 PMkarelpeeters
04/03/2019, 6:19 PMCzar
04/03/2019, 6:20 PMkarelpeeters
04/03/2019, 6:22 PMDominaezzz
04/03/2019, 8:40 PMoperator fun <E> ThreadLocal<E>.getValue(thisRef: Any?, property: KProperty<*>): E {
return get()
}
operator fun <E> ThreadLocal<E>.setValue(thisRef: Any?, property: KProperty<*>, value: E) {
set(value)
}
fun main() {
val sdf by ThreadLocal.withInitial { SimpleDateFormat("yyyy-MM-dd HH:mm:ss").apply {
timeZone = TimeZone.getTimeZone("UTC")
}}
for(i in 0 until 10 ) {
thread {
println("${Thread.currentThread().name} - ${System.identityHashCode(sdf)}) - ${sdf.format(Date())}")
}
}
}
Dico
04/03/2019, 9:13 PMThreadLocal
, override initialValue()
and use a crossinline
lambda there. ;)
As for whether it's a good idea - theres a reason why this doesn't exist in the standard library, which is that there is no way to clear the value (cleaning up your resources from the ThreadLocalMap of the thread once you're done) unless you have access to the delegate instance, instead of just the getter. Unless you make the type nullable, but I would advise against that.