https://kotlinlang.org logo
Title
p

Peng Wang

12/10/2021, 3:43 AM
@Composable
@Deprecated("Example with bug")
fun ListWithBug(myList: List<String>) {
    var items = 0

    Row(horizontalArrangement = Arrangement.SpaceBetween) {
        Column {
            for (item in myList) {
                Text("Item: $item")
                items++ // Avoid! Side-effect of the column recomposing.
            }
        }
        Text("Count: $items")
    }
}
I don't know why this code has thread-safe problem, can anyone explain ? https://developer.android.google.cn/jetpack/compose/mental-model#parallel
a

Albert Chang

12/10/2021, 4:08 AM
It's explained before:
Composable functions can run in parallel
This optimization means a composable function might execute within a pool of background threads.
Compose UI isn't multi-threaded now but it can be in the future.
p

Peng Wang

12/10/2021, 6:18 AM
Thanks for your answer,but in the above code, why does
items++
run on multiple threads?
items++
is not in a Composable, but just in a for-loop
z

zokipirlo

12/10/2021, 6:32 AM
If for loop can run parallel, then
items
is changed from multiple threads. Just use
forEachIndexed
I guess in that case.
p

Peng Wang

12/10/2021, 6:42 AM
Loop run parallel ? I don't think this is what Compose can do
a

Albert Chang

12/10/2021, 6:44 AM
ListWithBug
,
Row
,
Column
are all composables. The lambdas (
content
parameter) you passed to
Row
and
Column
are also composables.
p

Peng Wang

12/10/2021, 6:49 AM
But
items++
always run in one composable, so why thread unsafe ? I can understand if
items++
in the for loop is wrapped in a composable, but it isn't now
a

Albert Chang

12/10/2021, 6:50 AM
Text("Count: $items")
can be run in another thread.
p

Peng Wang

12/10/2021, 6:54 AM
So what the code wants to express is that
Text
and
Column
are parallel , not
items++
is parallel ?
Column
is inline right?it can't be in parallel with Text
a

Albert Chang

12/10/2021, 7:07 AM
I think the code is mainly intended to show that you should avoid side effects in your composables as it is incorrect even without multi-threaded composition. Multi-threaded composition just makes it "more" wrong.
☝️ 1
👌 1
As I said before,
The lambdas (
content
 parameter) you passed to 
Row
 and 
Column
 are also composables.
s

Sean McQuillan [G]

12/10/2021, 5:29 PM
Author here. The intention is to show that each restart scope may be run on a new thread. So the write in column is not thread safe with the read in row
👍 1
That said there's not currently multithreading and both are scopes are now inline so actually triggering this fault with this code would be hard ☺️
But in general code of this style is unsafe in compose (due to regular var write in lambda capture)
While here, it's worth saying that writing a MutableState is thread safe
Is there another (very simple) example that'd show this better?
👏 1