Depuis que j'ai utilisé coroutines seulement sur la JVM, je vais vous parler de la JVM en arrière-plan, il y a aussi des Kotlin Natif et Kotlin JavaScript mais ces backends pour Kotlin sont hors de ma portée.
Donc, nous allons commencer avec la comparaison de Kotlin coroutines à d'autres langues coroutines. Fondamentalement, vous devez savoir qu'il existe deux types de Coroutines: stackless et stackful. Kotlin implémente stackless coroutines - cela signifie que coroutine ne dispose pas de sa propre pile, et que le fait de limiter un peu ce que coroutine peut faire. Vous pouvez lire une bonne explication ici.
Exemples:
- Stackless: C#, Scala, Kotlin
- Stackful: Quasar, Javaflow
Ce que cela signifie que la coroutine est comme la lumière-poids de fil?
Cela signifie que coroutine dans Kotlin ne dispose pas de sa propre pile, il n'a pas de carte sur un thread natif, il ne nécessite pas de changement de contexte sur un processeur.
Quelle est la différence?
Fil - de manière préventive multitâche. (généralement).
Coroutine - collaboration multitâche.
Fil - géré par l'OS (généralement).
Coroutine - géré par un utilisateur.
Sont kotlin de coroutines effectivement en cours d'exécution en parallèle / en même temps?
Ça dépend, vous pouvez exécuter chaque coroutine dans son propre thread, ou vous pouvez exécuter tous les coroutines dans un thread ou un niveau fixé de pool de threads.
Plus sur la façon de coroutines exécuter ici.
Même dans un système multi-core, il y a seulement une coroutine cours d'exécution à un moment donné (est-il juste?)
Non, voir la réponse précédente.
Ici, je suis de départ de 100000 coroutines, ce qui se passe derrière ce code?
En fait, ça dépend. Mais supposons que vous écrivez le code suivant:
fun main(args: Array<String>) {
for (i in 0..100000) {
async(CommonPool) {
delay(1000)
}
}
}
Ce code s'exécute instantanément.
Parce que nous devons attendre les résultats de async
appel.
Donc, nous allons résoudre ce problème:
fun main(args: Array<String>) = runBlocking {
for (i in 0..100000) {
val job = async(CommonPool) {
delay(1)
println(i)
}
job.join()
}
}
Lorsque vous exécutez ce programme kotlin permettra de créer 2 * 100000 instances de Continuation
, ce qui va prendre quelques dizaines de Mo de RAM, et dans la console, vous verrez des nombres de 1 à 100000.
Donc permet de réécrire ce code de cette façon:
fun main(args: Array<String>) = runBlocking {
val job = async(CommonPool) {
for (i in 0..100000) {
delay(1)
println(i)
}
}
job.join()
}
Ce que nous réalisons maintenant? Maintenant nous allons créer seulement 100001 cas d' Continuation
, et c'est beaucoup mieux.
Chaque suite sera distribué et exécuté sur CommonPool (qui est une instance statique de ForkJoinPool).