Kotlin - каналы сопрограмм - они блокируют вызывающий поток? - PullRequest
1 голос
/ 18 мая 2019

Я знаю, что каналы являются экспериментальными, и мы можем думать о каналах так же, как о очереди блокировки в Java.сказанное позволяет взглянуть на этот простой блок кода :

fun main(args: Array<String>) {

    val channel = Channel<Int>()
    GlobalScope.launch {
        for (x in 1..50000) {
            println("from channel $x")
            channel.send(x * x)
        }
    }
    // here we print five received integers:
    runBlocking {repeat(5) { println(channel.receive()) }}
    println("Done!")

}

Я хотел бы знать, что происходит с остальными целыми числами.посмотрите на результат выполнения этого:

 from channel 1
1
from channel 2
from channel 3
4
9
from channel 4
from channel 5
16
from channel 6
25
Done!

почему он не напечатал все 50000 целых чисел?У меня есть это в глобальном масштабе.поэтому эта строка: println("from channel $x") должна была быть вызвана 50000 раз.почему не сделал?

Ответы [ 2 ]

1 голос
/ 19 мая 2019

Пропускная способность внутренней очереди канала по умолчанию равна 1. Это так называемый канал rendezvous , потому что производитель и сопрограмма потребителя должны встретиться для обмена предметом. Поскольку вы потребляете только пять предметов, производитель может произвести только пять из них и приостановить их работу, прежде чем доставить шестой, после чего вся ваша программа завершится.

Итак, вот модификация вашей программы, которая печатает все 50000 элементов:

fun main() {
    val channel = Channel<Int>(Channel.UNLIMITED)
    GlobalScope.launch {
        for (x in 1..50000) {
            println("from channel $x")
            channel.send(x * x)
        }
    }
    Thread.sleep(1000)
    println("Done!")
}

Обратите внимание, что в этот раз не было необходимости употреблять их.

1 голос
/ 18 мая 2019

send является функцией приостановки и блокирует сопрограмму (не нить), если на другом конце нет никого, чтобы получить / удалить из очереди.Именно так поддерживается обратное давление в мире сопрограмм.Ваш runBlocking повторяется только в течение 5 итераций и ваши основные выходы.

...