How do you code doing 16 jobs 51 asyncs/launches w...
# coroutines
e
How do you code doing 16 jobs 51 asyncs/launches with a for loop and the many not get messed up?
👀 1
u
Hi @Eric Womer did you read and understand @Sam’s answer? https://kotlinlang.slack.com/archives/C1CFAFJSK/p1674648841566549?thread_ts=1674647885.585549&cid=C1CFAFJSK I’d suggest first fixing that and then trying again. If you need help in understanding or fixing the race condition, feel free to ask.
e
@uli Basically I need to get the out put as a var, probably a list, from the deferred, correct?
So my theory was right that it was running multiple asyncs with the same data, like several of them had the starting value 17 instead of the series I was trying to create?
u
looked a bit at your code. and not sure what you are trying to do… you want to do 826 iterations and let’s say, you have 4 cores. Then you would start 826/4=206 jobs? I would expect you want to start 4 jobs with 206 iterations each.
e
I rewrote it that way yes, but for me in android stuidio it was 16 cores so 16 jobs 51 iterations and one last iteration of 10 (the remainder)
u
no. 51 jobs, 16 iterations
e
The 826 are ids that need to be passed to a method.
I flipped the math around, I thought it was silly to have the inner for loop only iterate 16 times, and create 51 jobs.
u
ah, corect
e
so the outside for loop would go 16 loops, and the inner would do 51
I wanted top put 51 iterations into the async so I could divide up the network call into several threads* all while having a valid counter to keep track of the ids already gotten.
u
So the 1st issue is that your upper bound in this for loop
Copy code
for (j in i..forCount) {
changes while the loop still itterates.
e
yup
u
This can be fixed like this:
Copy code
val upperBound = forCount
async(Dispatchers.Default) {
  for (j in i..upperBound) {
e
Would that work, when forCount is still being changed?
u
After that you will probably run into an issue with concurrent list modification. So yes, you need to return the lists as the deferred from async and then join the partial lists
e
yeah, through an theList.add(defferedList.await() /* or would it be awaitAll()? *?)
u
This can be done very elegant with a map/fold instead of a for loop along these lines:
Copy code
(1 .. (count - remainder) step cores).map { i-> 
  ...
  ...
  async { 
    // innerLoop
  }
}.awaitAll().flatten()
And it might be mathematically easier to count through the number of jobs and then calculate the indices belonging to the job:
Copy code
(0 until cores).map { core->
  async {
    val i0 = quotent * core
    val i1 = quotent * (core + 1) - 1
    ...
  }
}
e
So manually add each individual call to the async block?