ursus
10/17/2020, 5:07 AMMarc Knaup
10/17/2020, 5:15 AMlouiscad
10/17/2020, 5:33 AMsynchronized
over suspension points is not cool (expect issues), and should be replaced by Mutex
, but otherwise, it's fine in the JVM.ephemient
10/17/2020, 6:50 AM@Synchronized
just sets a flag on the method in the classfile, so it probably doesn't cause anything to break, but it won't work either; as far as the JVM is concerned, the function is being called and is returning at every suspension pointsynchronized(lock)
translates to monitorenter and monitorexit bytecode instructions. that will be problematic for sure as the object will stay locked on the original thread, but the coroutine may not be resumed thereursus
10/17/2020, 12:15 PMsynchronized {
stateFlow.value = stateFlow.value.copy(foo = bar)
}
Zach Klippenstein (he/him) [MOD]
10/17/2020, 2:42 PMMutableStateFlow
has a compareAndSet
method you can use for lock-free atomic updates: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-mutable-state-flow/compare-and-set.htmlephemient
10/17/2020, 11:03 PMursus
10/18/2020, 12:28 AMval mutableStateFlow = MutableStateFlow(State())
mutableStateFlow.set {
copy(counter + 1)
}
data class State(counter: Int = 0)
and have the set function be thread safeZach Klippenstein (he/him) [MOD]
10/18/2020, 12:33 AMlateinit var old: YourState
lateinit var new: YourState
do {
old = mutableStateFlow.value
new = old.copy(foo = bar)
} while (!mutableStateFlow.compareAndSet(old, new))
ursus
10/18/2020, 12:36 AMfun <T> MutableStateFlow<T>.set(reduce: T.() -> T) {
synchronized(this) {
value = value.reduce()
}
}
so the difference is the classic lock vs lockfree concurrency thing? nothing coroutine about this right?Zach Klippenstein (he/him) [MOD]
10/18/2020, 12:40 AMursus
10/18/2020, 12:41 AMZach Klippenstein (he/him) [MOD]
10/18/2020, 12:53 AMursus
10/18/2020, 12:56 AMlouiscad
10/18/2020, 2:41 AMursus
10/18/2020, 2:42 AMlouiscad
10/18/2020, 3:00 AMephemient
10/18/2020, 4:16 AMursus
10/18/2020, 5:17 AMephemient
10/18/2020, 7:05 AMursus
10/18/2020, 3:24 PMephemient
10/20/2020, 8:05 AMsuspend fun foo(lock: Any, block: suspend () -> Unit) {
synchronized(lock) {
block()
}
}
foo.kt:3:9: error: the 'invoke' suspension point is inside a critical section
block()
^
ursus
10/25/2020, 2:12 PMephemient
10/25/2020, 2:31 PMursus
10/25/2020, 2:36 PMephemient
10/25/2020, 2:37 PMursus
10/25/2020, 2:42 PMephemient
10/25/2020, 4:13 PM