https://kotlinlang.org logo
#coroutines
Title
# coroutines
g

groostav

08/09/2018, 6:54 PM
Copy code
val notThreadSafe: Int? = null

fun doStuff() = runBlocking {
  val updateJob = launch(CommonPool) { notThreadSafe = 1 }

  updateJob.join()
  val result = notThreadSafe // <- no gaurentee this isnt null, in fact theres no gaurentee that your thread will _ever_ see the value `1` on that field.
}
this is true despite happens before semantics. the assignment of
1
to
notThreadSafe
happens before the assignment of
notThreadSafe
to
result
, but because its not marked as
@Volatile
you have no gaurentees about when the value
notTHreadSafe
will actually be written to main memory. Your only gaurentee is that all downstream operations on that thread on the common pool will see the value
1
for not thread safe. I could be mistaken. Java Concurrency in Practice is a uniquely horrifying book to read.
e

elizarov

08/09/2018, 8:49 PM
I does not have to be volatile. Happens-before is guaranteed by
join
and that is enough (and it has to be
var
). You can read my shorting explanation here: https://proandroiddev.com/what-is-concurrent-access-to-mutable-state-f386e5cb8292
🤔 1
g

groostav

08/09/2018, 9:22 PM
so, I don't understand how. Where can I learn about the device you're using to do this? does java byte code support special fencing instructions that you're using from
suspendOrReturn
and similar to achieve this? I should add I've been silly thinking that this was just a problem if you moved between dispatchers, forgetting that dispatchers typically represent pools, not single threads, so of course this problem would have to be solved else
CommonPool
would be utterly useless!
g

gildor

08/09/2018, 11:08 PM
Hm, looks that your example is incorrect, you cannot call .join() outside of suspend context, probably doStuff should be suspend
✔️ 1
e

elizarov

08/10/2018, 6:44 AM
@groostav Start with my blog post I’ve linked to. Then you can read JCIP and/or the corresponding JLS chapter. In short, “happens-before” is established by “synchronization actions”. And “join” implementation is using those under the hood. You only need volatile to establish happens-before, as volatile reads/writes are synchronization actions.
2 Views