Мультиплатформенная параллельная изменчивость Kotlin iOS против Android

#kotlin-multiplatform #kotlin-multiplatform-mobile

Вопрос:

Я знаю, что у Kotlin/Native есть очень специфические правила в отношении изменчивости объектов между потоками.

Однако, к моему удивлению, я обнаружил, что при запуске модульных тестов из commonMain (развернутого в androidTestDebug) я могу изменять изменяемые состояния в разных потоках. Например, это отлично работает при изменении значения в MyData :

 data class MyData(var value : Int = 0)

suspend fun main() = coroutineScope {
  val myData = MyData()
  val newContext1 = newSingleThreadContext("contextOne")
  val newContext2 = newSingleThreadContext("contextTwo")

  launch (newContext1) {
    myData.value = 1
  }
  launch (newContext2) {
    myData.value = 2
  }
}
 

Однако, если я запущу это, ориентируясь на iOS, он выйдет из строя, что даст мне kotlin.native.concurrent.InvalidMutabilityException . Это то, что я ожидал бы увидеть на обеих платформах. Я новичок в KMM, но почему при запуске кода commonMain на JVM не применяются правила одновременной изменяемости?

Кроме того, есть ли способ принудительно ввести правила изменяемости в JVM, чтобы тесты не выполнялись на Android так же, как и на iOS? Я думаю, что это помогло бы обеспечить согласованность платформы.

Ответ №1:

Нет, это не должно произойти на Android.

Kotlin native создает собственный код из Kotlin, поэтому существует необходимость в его собственной модели параллелизма.

Для части Android это простой код kotlin, поэтому можно использовать модель параллелизма JVM, и, как и любой другой код kotlin, который изменяет переменную, он не должен аварийно завершаться.

Я не думаю, что есть способ заставить его рухнуть на Android.

В kotlin 1.6.0 это следует изменить, чтобы этот код не зависал на обеих платформах