You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The following code behaves in a way that seems pretty counter-intuitive:
val myLazyVal by lazy {
println("Running lazy initializer!")
runBlocking {
someSuspendFunctionForInitialization()
}
}
funmain() = runBlocking {
coroutineScope {
(0 until 10).map {
launch { myLazyVal.someOperation() }
}
}
}
With that code the lazy initializer can run multiple times.
Here is my understanding of why it happens, please correct me if I'm wrong:
We launched 10 coroutines that all try to access myLazyVal.
When the first coroutine gets suspended during the lazy initialization, the second one may very well be resumed on the same thread
I'm guessing the synchronized(lock) { ... } block used by SynchronizedLazyImpl is re-entrant and therefore lets the second coroutine re-enter the synchronized block, leading to multiple simultaneous initializations.
The text was updated successfully, but these errors were encountered:
It's not exactly that, but the idea is similar.
After #860 nested runBlocking do not deadlock each other but form a shared event loop. When the coroutine suspends in someSuspendFunctionForInitialization, nested runBlocking starts executing coroutines from the outer ones, that are able to execute lazy initializer because of lock re-entrancy
It's not exactly that, but the idea is similar.
After #860 nested runBlocking do not deadlock each other but form a shared event loop. When the coroutine suspends in someSuspendFunctionForInitialization, nested runBlocking starts executing coroutines from the outer ones, that are able to execute lazy initializer because of lock re-entrancy
@qwwdfsad coroutine doesn't have identity(unlike thread), so similar bug can't be solved, even in the future?
(this specific lazy val can be solved of course, but similar synchronized or lock reentrant ones
It's not exactly an identity problem but rather a corner case of the edge of even loops and reentrant JVM locks. Over the course of years, we haven't really found an elegant solution for this particular problem, so it's unlikely to ba changed in the future
The following code behaves in a way that seems pretty counter-intuitive:
With that code the lazy initializer can run multiple times.
Here is my understanding of why it happens, please correct me if I'm wrong:
synchronized(lock) { ... }
block used bySynchronizedLazyImpl
is re-entrant and therefore lets the second coroutine re-enter the synchronized block, leading to multiple simultaneous initializations.The text was updated successfully, but these errors were encountered: