https://kotlinlang.org logo
Title
i

igor.wojda

04/29/2020, 7:24 PM
I have implemented a sleep sort algorithm using coroutines (don’t ask me why🤣) and now Vasya asks me if this implementation is thread-safe? And now I really wonder if it is thread-save to access
sortedList
like this? https://twitter.com/igorwojda/status/1255416485293502465
a

araqnid

04/29/2020, 7:27 PM
(JVM) the mutableListOf returns a LinkedHashSet, which is not concurrent-modification safe (although it seems unlikely you’d hit that in this example, with the writes guaranteed to be 1sec apart)
👍 1
o

octylFractal

04/29/2020, 7:29 PM
if you use a single-threaded dispatcher like
Dispatchers.Main
(if you have it) or
Executors.newSingleThreadExecutor().asDispatcher()
, you could actually make this thread safe
👍 1
e

Evan R.

04/29/2020, 7:29 PM
Also, don’t use GlobalScope if you can avoid it! Errors won’t be thrown properly
o

octylFractal

04/29/2020, 7:29 PM
err, rather, not "thread safe" but it wouldn't be cross-thread anymore
d

Dominaezzz

04/29/2020, 7:30 PM
Cool sort though. 😁
o

octylFractal

04/29/2020, 7:30 PM
and yes, the solution to not use GlobalScope here is to do:
coroutineScope {
  for (elm in list) {
    launch(properDispatcher) {
      delay(1000L * elm)
      sortedList.add(elm)
    }
  }
}
e

Evan R.

04/29/2020, 7:30 PM
Instead, use the
coroutineScope()
builder and either a mutex or a channel to control access to the shared list lol
Here’s how you can do it with a channel:
d

Dominaezzz

04/29/2020, 7:31 PM
Should actually be
launch
.
o

octylFractal

04/29/2020, 7:31 PM
ah, yes
d

Dominaezzz

04/29/2020, 7:32 PM
Should also leave the dispatcher to be inherited from context.
o

octylFractal

04/29/2020, 7:33 PM
well, I was assuming a patch with the new dispatcher, so you'd either have to wrap the
coroutineScope
or the loop with
withContext
in that case
e

Evan R.

04/29/2020, 7:35 PM
The above snippet is thread-safe due to only the receiver coroutine mutating the list 🙂
👍 1
d

Dominaezzz

04/29/2020, 7:36 PM
Might as well go all the way and do
channelFlow { ... }.toList()
. 😁
👍 2
e

Evan R.

04/29/2020, 7:37 PM
That too lol
k

Kroppeb

04/29/2020, 8:47 PM
Ideally, you'd have a way shorter delay, and add a insertion sort final step