Каналы Kotlin, используемые в сопрограммах, поддерживают потокобезопасность / синхронизацию / поддерживают связь до появления? - PullRequest
0 голосов
/ 04 февраля 2019

Функции, доступные в каналах Kotlin, безопасны для потоков?например,

val channel = Channel<Boolean>()
val job1 = GlobalScope.launch {
    channel.send(true)
}
val job2 = GlobalScope.launch {
    val x = channel.poll()
}

Если в приведенном выше коде job1 было выполнено машиной (в режиме реального времени) перед выполнением job2 и в других потоках, гарантируется ли, что x установлен с true?Или возможно, что он установлен с null (поскольку кэш процессора не был обновлен)?

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Если в приведенном выше коде job1 было выполнено машиной (в режиме реального времени) перед выполнением job2 и в других потоках, гарантируется ли, что x установлено с true?Или возможно, что он установлен с null (потому что кэш процессора не был обновлен)?

Модель памяти Java не имеет представления о времени, и она не гарантирует ничего, основываясь только наДело в том, что строка выполнена раньше, чем другая.Вы даже не можете определить, когда действие было выполнено на процессоре.

В опубликованном вами коде есть две одновременно выполняющиеся сопрограммы. В том и только в том случае, если channel.poll() получает ненулевое значение, существует произойдет до того, как ребро перейдет от send() до poll().Если он получает нулевое значение, не происходит до края.

Допустим, вы определяете время настенных часов в двух сопрограммах, что-то вроде следующего:

var sendTime: Long = 0
var receiveTime: Long = 0

suspend fun main() {
    val channel = Channel<Boolean>(UNLIMITED)
    val job1 = GlobalScope.launch {
        channel.send(true)
        sendTime = System.nanoTime()
    }
    val job2 = GlobalScope.launch {
        receiveTime = System.nanoTime()
        val x = channel.poll()
        println(x)
    }
    job1.join()
    job2.join()
    println("${receiveTime - sendTime}")
}

Тот факт, что receiveTime больше sendTime, не вызываетОтношения случаются до , и channel.poll() не заставляет наблюдать отправленный элемент.Вызов nanoTime() не является действием синхронизации.

Обратите внимание, что эти факты не имеют ничего общего с Kotlin или сопрограммами, именно так работает модель памяти Java.Если вы изучите модель памяти C ++, вы обнаружите, что она работает так же.

0 голосов
/ 04 февраля 2019
Библиотека

Channel class kotlinx.coroutines является поточно-ориентированной.Он предназначен для поддержки нескольких потоков.

GlobalScope.launch не обязательно означает, что сопрограмма будет выполнена в новом потоке

...