SlideShare una empresa de Scribd logo
1 de 37
Descargar para leer sin conexión
Kotlin from scratch 3
franco.lombardo@smeup.com - https://www.linkedin.com/in/francolombardo/
Coroutines
Danger zone!!!
Photo by Vladyslav Cherkasenko on Unsplash
See the example project
https://github.com/f-lombardo/kotlin-from-scratch
What is a thread?
A thread is the smallest sequence of programmed instructions that can be
managed independently by the operating system scheduler. (Wikipedia)
fun main(args: Array<String>) {
thread(start = true, name = "Calandrino", isDaemon = true) {
while(true) {
logMsg("So' bischero!")
BigInteger.probablePrime(3072, Random())
}
}
Thread {
while(true) {
logMsg("Io pitto!")
BigInteger.probablePrime(3072, Random())
}
}.apply { name = "Buffalmacco" }.start()
}
Threads are operating system objects
At least on *nix systems!
Threads are operating system objects
And on IBM i / AS400! (WRKJVMJOB command)
What is a coroutine?
Coroutines generalize subroutines for non-preemptive multitasking, by
allowing execution to be suspended and resumed.
Coroutines are very similar to threads. However, coroutines are
cooperatively multitasked, whereas threads are typically
preemptively multitasked. This means that coroutines provide
concurrency but not parallelism. (Wikipedia)
Subroutines: objects defined by the programming language, not by the
operating system.
Parallelism
Photo by kakei lam on Unsplash
Parallelism
Calandrino thread Calandrino’s computation
Buffalmacco thread Buffalmaccos’s computation
Concurrency
By Backlit - Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=12225421
Concurrency
Main thread Calandrino Buffalmacco
Suspended coroutines
Calandrino Buffalmacco
How to create a coroutine?
1) In build.gradle add the dependency to
org.jetbrains.kotlinx:kotlinx-coroutines-core:version_nbr
2) There is a system property to set if you want to see more coroutine infos
System.setProperty("kotlinx.coroutines.debug", "")
How to create a coroutine?
fun main(args: Array<String>) = runBlocking {
async(CoroutineName("Calandrino")) {
while (true) {
logMsg("So' bischero!")
BigInteger.probablePrime(1024, Random())
}
}
async(CoroutineName("Buffalmacco")) {
while (true) {
logMsg("Io pitto!")
BigInteger.probablePrime(1024, Random())
}
}
}
runBlocking, async (and launch) are coroutines builders
It doesn’t work as expected!
fun main(args: Array<String>) = runBlocking {
async(CoroutineName("Calandrino")) {
while (true) {
logMsg("So' bischero!")
BigInteger.probablePrime(1024, Random())
}
}
async(CoroutineName("Buffalmacco")) {
while (true) {
logMsg("Io pitto!")
BigInteger.probablePrime(1024, Random())
}
}
}
It just prints “So’ bischero!”
Remember: we have to collaborate!
fun main(args: Array<String>) = runBlocking {
async(CoroutineName("Calandrino")) {
while (true) {
logMsg("So' bischero!")
BigInteger.probablePrime(1024, Random())
yield()
}
}
async(CoroutineName("Buffalmacco")) {
while (true) {
logMsg("Io pitto!")
BigInteger.probablePrime(1024, Random())
yield()
}
}
} yield gives control to other coroutines
How to collaborate?
yield gives control to other coroutines
How to collaborate?
delay is like Thread.sleep
Collaborating using delay
fun main(args: Array<String>) = runBlocking {
async(CoroutineName("Calandrino")) {
while (true) {
logMsg("So' bischero!")
BigInteger.probablePrime(1024, Random())
delay(10)
}
}
async(CoroutineName("Buffalmacco")) {
while (true) {
logMsg("Io pitto!")
BigInteger.probablePrime(1024, Random())
delay(10)
}
}
}
await waits for another coroutine to complete
How to collaborate?
Collaborating using await
fun main(args: Array<String>) {
runBlocking {
async(CoroutineName("Calandrino")) {
while (true) {
val deferredNumber: Deferred<BigInteger> = async { bigPrime() }
logMsg("Bischerata numero ${deferredNumber.await()}")
}
}
async(CoroutineName("Buffalmacco")) {
while (true) {
val deferredNumber: Deferred<BigInteger> = async { bigPrime() }
logMsg("Clandrino è bischero ${deferredNumber.await()} volte!")
}
}
}
}
Collaborating using await
fun main(args: Array<String>) {
runBlocking {
async(CoroutineName("Calandrino")) {
while (true) {
logMsg("Bischerata numero ${bigPrime()}")
}
}
async(CoroutineName("Buffalmacco")) {
while (true) {
logMsg("Calandrino è bischero ${bigPrime()} volte!")
}
}
}
}
It doesn’t work because Calandrino keeps the thread!
Collaborating using await
fun main(args: Array<String>) {
runBlocking {
async(CoroutineName("Calandrino")) {
while (true) {
logMsg("Bischerata numero ${bigPrime()}")
}
}
async(CoroutineName("Buffalmacco")) {
while (true) {
logMsg("Calandrino è bischero ${bigPrime()} volte!")
}
}
}
}
It doesn’t work because Calandrino keeps the thread!
(Bischero!)
suspend fun calandrinate() {
while (true) {
logMsg("So' bischero!")
BigInteger.probablePrime(1024, Random())
yield()
}
}
async(CoroutineName("Calandrino")) {
calandrinate()
}
Collaborating functions are
suspending ones
async(CoroutineName("Calandrino")) {
while (true) {
logMsg("So' bischero!")
BigInteger.probablePrime(1024, Random())
yield()
}
}
suspend fun calandrinate() {
while (true) {
logMsg("So' bischero!")
BigInteger.probablePrime(1024, Random())
yield()
}
}
Collaborating functions are
suspending ones
The suspend modifier does not make a function
either asynchronous or non-blocking.
It just tells that the function could be suspended, as it could call other
suspending functions (such as yield or delay).
Anyway, it’s a good convention to create suspending functions that don’t
block the calling thread.
async and launch builders
need a scope!
CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async {
bigPrime(1024)
}
The async and launch coroutines builders are extension functions for
the CoroutineScope interface, so they must be called on an object of
that type.
When you see them called without an explicit scope, as inside
runBlocking, it is because they are called in a block that provides an
implicit this receiver of type CoroutineScope.
async and launch builders
need a scope!
CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async {
bigPrime(1024)
}
A CoroutineScope holds information on how to run coroutines, using a
CoroutineContext object.
We can create one of them with:
• the CoroutineScope factory function;
• the MainScope factory function: this works for Android, Swing and
JavaFx applications, pointing to the Main UI thread;
• the GlobalScope object, for top-level coroutines which are operating
on the whole application lifetime;
• the runBlocking function, that creates an implicit CoroutinesScope
receiver;
• the coroutineScope function (inside a suspend function/coroutine).
async and launch builders
need a scope!
CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async {
bigPrime(1024)
}
A CoroutineContext is something like a “set” of properties related to
the coroutine.
Each element of a CoroutineContext is a CoroutineContext too.
Elements can be added with the + operator.
So, whenever we have a CoroutineContext parameter, we can pass
just one type of information, that will override the existing one, or a
concatenated set of elements.
async and launch builders
need a scope!
Whenever we have a CoroutineContext parameter, we can pass just
one type of information, that will override the existing one, or a
concatenated set of elements.
The type of these three expression is CoroutineContext:
• Dispatchers.Unconfined
• CoroutineName("Calandrino")
• Dispatchers.Unconfined + CoroutineName("Calandrino")
CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async {
bigPrime(1024)
}
async and launch builders
need a scope!
CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async {
bigPrime(1024)
}
An important type of CoroutineContext element is the Dispatcher,
that defines the thread running the coroutine.
async and launch builders
need a scope!
CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async {
bigPrime(1024)
}
Types of dispatchers:
• Dispatcher.Default: backed by a shared pool of threads with
maximum size equal to the number of CPU cores; for CPU/bound
tasks;
• Dispatcher.IO: for offloading blocking IO tasks to a shared pool of
threads (the default is 64);
• Dispatcher.Main: main UI thread in Android/Swing applications;
• Dispathcer.Unconfined: not confined to any specific thread. The
coroutine executes in the current thread first and lets the coroutine
resume in whatever thread.
async and launch builders
need a scope!
CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async {
bigPrime(1024)
}
Dispatcher can also be created with these functions:
• newSingleThreadContext: one thread per coroutine;
• newFixedThreadPoolContex: a fixed size thread pool;
• asCoroutineDispatcher extension function on Java Executor.
The launch builder
fun main(args: Array<String>) = runBlocking {
val job: Job = launch(Dispatchers.Unconfined) {
ConsoleProgressBar().showContinuously()
}
println("A big prime number: ${bigPrime(2048)}")
job.cancel()
}
The launch builder returns a Job that can be used to control the execution
of the coroutine.
Parent-child hierarchies for Jobs
Parent jobs wait the end of all their children
Cancellation of a parent leads to immediate cancellation of all its children
fun main(args: Array<String>) = runBlocking {
val job: Job = launch(Dispatchers.Unconfined) {
launch {
launch {
delayAndLog()
}
delayAndLog()
}
delayAndLog()
}
println("Here is a big prime number: ${bigPrime(2048)}")
job.cancel()
}
Why coroutines?
(1..100_000).forEach {
launch {
while (true) delay(10_000)
}
}
Why coroutines?
(1..10_000).forEach {
thread(start = true) {
while (true) Thread.sleep(10_000)
}
}
Why coroutines?
(1..10_000).forEach {
thread(start = true) {
while (true) Thread.sleep(10_000)
}
}
By the way: it works on Windows! J
Good reads
Kotlin Coroutines in Android - Basics
https://medium.com/swlh/kotlin-coroutines-in-android-basics-9904c98d4714
Concurrency is not parallelism
https://kotlinexpertise.com/kotlin-coroutines-concurrency/
Blocking threads, suspending coroutines
https://medium.com/@elizarov/blocking-threads-suspending-coroutines-d33e11bf4761
Coroutines: Suspending State Machines
https://medium.com/google-developer-experts/coroutines-suspending-state-machines-36b189f8aa60
Coroutines hands-on
https://play.kotlinlang.org/hands-on/Introduction%20to%20Coroutines%20and%20Channels/

Más contenido relacionado

La actualidad más candente

Python, async web frameworks, and MongoDB
Python, async web frameworks, and MongoDBPython, async web frameworks, and MongoDB
Python, async web frameworks, and MongoDBemptysquare
 
Do we need Unsafe in Java?
Do we need Unsafe in Java?Do we need Unsafe in Java?
Do we need Unsafe in Java?Andrei Pangin
 
Python twisted
Python twistedPython twisted
Python twistedMahendra M
 
Tornado web
Tornado webTornado web
Tornado webkurtiss
 
Understanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring EffectsUnderstanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring EffectsShinpei Hayashi
 
Nginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/sNginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/smoret1979
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Java Concurrency Idioms
Java Concurrency IdiomsJava Concurrency Idioms
Java Concurrency IdiomsAlex Miller
 
Tornado Web Server Internals
Tornado Web Server InternalsTornado Web Server Internals
Tornado Web Server InternalsPraveen Gollakota
 
Android Performance #4: Network
Android Performance #4: NetworkAndroid Performance #4: Network
Android Performance #4: NetworkYonatan Levin
 
Rust: Unlocking Systems Programming
Rust: Unlocking Systems ProgrammingRust: Unlocking Systems Programming
Rust: Unlocking Systems ProgrammingC4Media
 
MongoUK 2011 - Rplacing RabbitMQ with MongoDB
MongoUK 2011 - Rplacing RabbitMQ with MongoDBMongoUK 2011 - Rplacing RabbitMQ with MongoDB
MongoUK 2011 - Rplacing RabbitMQ with MongoDBBoxed Ice
 
Java Concurrency in Practice
Java Concurrency in PracticeJava Concurrency in Practice
Java Concurrency in Practiceericbeyeler
 
node.js and native code extensions by example
node.js and native code extensions by examplenode.js and native code extensions by example
node.js and native code extensions by examplePhilipp Fehre
 
Python multithreading session 9 - shanmugam
Python multithreading session 9 - shanmugamPython multithreading session 9 - shanmugam
Python multithreading session 9 - shanmugamNavaneethan Naveen
 
Concurrency in Python
Concurrency in PythonConcurrency in Python
Concurrency in PythonGavin Roy
 

La actualidad más candente (20)

Python, async web frameworks, and MongoDB
Python, async web frameworks, and MongoDBPython, async web frameworks, and MongoDB
Python, async web frameworks, and MongoDB
 
Do we need Unsafe in Java?
Do we need Unsafe in Java?Do we need Unsafe in Java?
Do we need Unsafe in Java?
 
Web streams
Web streamsWeb streams
Web streams
 
Python twisted
Python twistedPython twisted
Python twisted
 
Tornado web
Tornado webTornado web
Tornado web
 
Understanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring EffectsUnderstanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring Effects
 
Nginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/sNginx + Tornado = 17k req/s
Nginx + Tornado = 17k req/s
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Java Concurrency Idioms
Java Concurrency IdiomsJava Concurrency Idioms
Java Concurrency Idioms
 
Tornado Web Server Internals
Tornado Web Server InternalsTornado Web Server Internals
Tornado Web Server Internals
 
Android Performance #4: Network
Android Performance #4: NetworkAndroid Performance #4: Network
Android Performance #4: Network
 
Intro to Sail.js
Intro to Sail.jsIntro to Sail.js
Intro to Sail.js
 
Rust: Unlocking Systems Programming
Rust: Unlocking Systems ProgrammingRust: Unlocking Systems Programming
Rust: Unlocking Systems Programming
 
MongoUK 2011 - Rplacing RabbitMQ with MongoDB
MongoUK 2011 - Rplacing RabbitMQ with MongoDBMongoUK 2011 - Rplacing RabbitMQ with MongoDB
MongoUK 2011 - Rplacing RabbitMQ with MongoDB
 
Node.js 0.8 features
Node.js 0.8 featuresNode.js 0.8 features
Node.js 0.8 features
 
Java Concurrency in Practice
Java Concurrency in PracticeJava Concurrency in Practice
Java Concurrency in Practice
 
Node.js in production
Node.js in productionNode.js in production
Node.js in production
 
node.js and native code extensions by example
node.js and native code extensions by examplenode.js and native code extensions by example
node.js and native code extensions by example
 
Python multithreading session 9 - shanmugam
Python multithreading session 9 - shanmugamPython multithreading session 9 - shanmugam
Python multithreading session 9 - shanmugam
 
Concurrency in Python
Concurrency in PythonConcurrency in Python
Concurrency in Python
 

Similar a Kotlin from-scratch 3 - coroutines

Aplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackAplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackNelson Glauber Leal
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksMongoDB
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackNelson Glauber Leal
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackNelson Glauber Leal
 
droidcon Transylvania - Kotlin Coroutines
droidcon Transylvania - Kotlin Coroutinesdroidcon Transylvania - Kotlin Coroutines
droidcon Transylvania - Kotlin CoroutinesArthur Nagy
 
Improving app performance with Kotlin Coroutines
Improving app performance with Kotlin CoroutinesImproving app performance with Kotlin Coroutines
Improving app performance with Kotlin CoroutinesHassan Abid
 
Deep Dive into Zone.JS
Deep Dive into Zone.JSDeep Dive into Zone.JS
Deep Dive into Zone.JSIlia Idakiev
 
.NET Multithreading/Multitasking
.NET Multithreading/Multitasking.NET Multithreading/Multitasking
.NET Multithreading/MultitaskingSasha Kravchuk
 
Structured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin CoroutinesStructured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin CoroutinesVadims Savjolovs
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSuzquiano
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the wayOleg Podsechin
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackAplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackNelson Glauber Leal
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineRicardo Silva
 
Understanding Scratch Extensions with JavaScript (Part 2 of 2)
Understanding Scratch Extensions with JavaScript (Part 2 of 2)Understanding Scratch Extensions with JavaScript (Part 2 of 2)
Understanding Scratch Extensions with JavaScript (Part 2 of 2)Darren Adkinson
 
Java design patterns
Java design patternsJava design patterns
Java design patternsShawn Brito
 
An opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathonAn opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathonLuciano Mammino
 
Kotlin - Coroutine
Kotlin - CoroutineKotlin - Coroutine
Kotlin - CoroutineSean Tsai
 

Similar a Kotlin from-scratch 3 - coroutines (20)

Aplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackAplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e Jetpack
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
 
droidcon Transylvania - Kotlin Coroutines
droidcon Transylvania - Kotlin Coroutinesdroidcon Transylvania - Kotlin Coroutines
droidcon Transylvania - Kotlin Coroutines
 
Improving app performance with Kotlin Coroutines
Improving app performance with Kotlin CoroutinesImproving app performance with Kotlin Coroutines
Improving app performance with Kotlin Coroutines
 
Deep Dive into Zone.JS
Deep Dive into Zone.JSDeep Dive into Zone.JS
Deep Dive into Zone.JS
 
.NET Multithreading/Multitasking
.NET Multithreading/Multitasking.NET Multithreading/Multitasking
.NET Multithreading/Multitasking
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Structured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin CoroutinesStructured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin Coroutines
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMS
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
Java Concurrency
Java ConcurrencyJava Concurrency
Java Concurrency
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackAplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & Jetpack
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 Engine
 
Understanding Scratch Extensions with JavaScript (Part 2 of 2)
Understanding Scratch Extensions with JavaScript (Part 2 of 2)Understanding Scratch Extensions with JavaScript (Part 2 of 2)
Understanding Scratch Extensions with JavaScript (Part 2 of 2)
 
Nodejs Intro Part One
Nodejs Intro Part OneNodejs Intro Part One
Nodejs Intro Part One
 
Java design patterns
Java design patternsJava design patterns
Java design patterns
 
An opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathonAn opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathon
 
Kotlin - Coroutine
Kotlin - CoroutineKotlin - Coroutine
Kotlin - Coroutine
 

Más de Franco Lombardo

Kotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsKotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsFranco Lombardo
 
Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)
Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)
Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)Franco Lombardo
 
Unit testing on AS400? Yes we can! (With Kotlin)
Unit testing on AS400? Yes we can! (With Kotlin)Unit testing on AS400? Yes we can! (With Kotlin)
Unit testing on AS400? Yes we can! (With Kotlin)Franco Lombardo
 
Interprete Kotlin per l’RPG e libreria Web Components: Open Source per la m...
Interprete Kotlin per l’RPG  e libreria Web Components: Open Source per  la m...Interprete Kotlin per l’RPG  e libreria Web Components: Open Source per  la m...
Interprete Kotlin per l’RPG e libreria Web Components: Open Source per la m...Franco Lombardo
 
TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019
TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019
TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019Franco Lombardo
 
Un interprete Kotlin per il linguaggio RPG AS400 - IBM i
Un interprete Kotlin per il linguaggio RPG AS400 - IBM iUn interprete Kotlin per il linguaggio RPG AS400 - IBM i
Un interprete Kotlin per il linguaggio RPG AS400 - IBM iFranco Lombardo
 
Agile Happiness - Agile O'Day 2018
Agile Happiness - Agile O'Day 2018Agile Happiness - Agile O'Day 2018
Agile Happiness - Agile O'Day 2018Franco Lombardo
 
Rock scissors-paper-kata
Rock scissors-paper-kataRock scissors-paper-kata
Rock scissors-paper-kataFranco Lombardo
 
Primo Incontro Con Scala
Primo Incontro Con ScalaPrimo Incontro Con Scala
Primo Incontro Con ScalaFranco Lombardo
 

Más de Franco Lombardo (15)

happiness_2023.pdf
happiness_2023.pdfhappiness_2023.pdf
happiness_2023.pdf
 
Kotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsKotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functions
 
Kotlin from-scratch
Kotlin from-scratchKotlin from-scratch
Kotlin from-scratch
 
Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)
Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)
Agile Venture Milan - Unit testing on AS400? Yes we can! (With Kotlin)
 
Unit testing on AS400? Yes we can! (With Kotlin)
Unit testing on AS400? Yes we can! (With Kotlin)Unit testing on AS400? Yes we can! (With Kotlin)
Unit testing on AS400? Yes we can! (With Kotlin)
 
Interprete Kotlin per l’RPG e libreria Web Components: Open Source per la m...
Interprete Kotlin per l’RPG  e libreria Web Components: Open Source per  la m...Interprete Kotlin per l’RPG  e libreria Web Components: Open Source per  la m...
Interprete Kotlin per l’RPG e libreria Web Components: Open Source per la m...
 
TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019
TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019
TDD su AS400? Con Kotlin si può fare! - Italian Agile Days 2019
 
Un interprete Kotlin per il linguaggio RPG AS400 - IBM i
Un interprete Kotlin per il linguaggio RPG AS400 - IBM iUn interprete Kotlin per il linguaggio RPG AS400 - IBM i
Un interprete Kotlin per il linguaggio RPG AS400 - IBM i
 
Agile Happiness - Agile O'Day 2018
Agile Happiness - Agile O'Day 2018Agile Happiness - Agile O'Day 2018
Agile Happiness - Agile O'Day 2018
 
Agile Happiness 2
Agile Happiness 2Agile Happiness 2
Agile Happiness 2
 
Agile Happiness
Agile HappinessAgile Happiness
Agile Happiness
 
Java per as400
Java per as400Java per as400
Java per as400
 
Rock scissors-paper-kata
Rock scissors-paper-kataRock scissors-paper-kata
Rock scissors-paper-kata
 
A First Date With Scala
A First Date With ScalaA First Date With Scala
A First Date With Scala
 
Primo Incontro Con Scala
Primo Incontro Con ScalaPrimo Incontro Con Scala
Primo Incontro Con Scala
 

Último

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfCionsystems
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....ShaimaaMohamedGalal
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 

Último (20)

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdf
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 

Kotlin from-scratch 3 - coroutines

  • 1. Kotlin from scratch 3 franco.lombardo@smeup.com - https://www.linkedin.com/in/francolombardo/ Coroutines
  • 2. Danger zone!!! Photo by Vladyslav Cherkasenko on Unsplash
  • 3. See the example project https://github.com/f-lombardo/kotlin-from-scratch
  • 4. What is a thread? A thread is the smallest sequence of programmed instructions that can be managed independently by the operating system scheduler. (Wikipedia) fun main(args: Array<String>) { thread(start = true, name = "Calandrino", isDaemon = true) { while(true) { logMsg("So' bischero!") BigInteger.probablePrime(3072, Random()) } } Thread { while(true) { logMsg("Io pitto!") BigInteger.probablePrime(3072, Random()) } }.apply { name = "Buffalmacco" }.start() }
  • 5. Threads are operating system objects At least on *nix systems!
  • 6. Threads are operating system objects And on IBM i / AS400! (WRKJVMJOB command)
  • 7. What is a coroutine? Coroutines generalize subroutines for non-preemptive multitasking, by allowing execution to be suspended and resumed. Coroutines are very similar to threads. However, coroutines are cooperatively multitasked, whereas threads are typically preemptively multitasked. This means that coroutines provide concurrency but not parallelism. (Wikipedia) Subroutines: objects defined by the programming language, not by the operating system.
  • 8. Parallelism Photo by kakei lam on Unsplash
  • 9. Parallelism Calandrino thread Calandrino’s computation Buffalmacco thread Buffalmaccos’s computation
  • 10. Concurrency By Backlit - Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=12225421
  • 11. Concurrency Main thread Calandrino Buffalmacco Suspended coroutines Calandrino Buffalmacco
  • 12. How to create a coroutine? 1) In build.gradle add the dependency to org.jetbrains.kotlinx:kotlinx-coroutines-core:version_nbr 2) There is a system property to set if you want to see more coroutine infos System.setProperty("kotlinx.coroutines.debug", "")
  • 13. How to create a coroutine? fun main(args: Array<String>) = runBlocking { async(CoroutineName("Calandrino")) { while (true) { logMsg("So' bischero!") BigInteger.probablePrime(1024, Random()) } } async(CoroutineName("Buffalmacco")) { while (true) { logMsg("Io pitto!") BigInteger.probablePrime(1024, Random()) } } } runBlocking, async (and launch) are coroutines builders
  • 14. It doesn’t work as expected! fun main(args: Array<String>) = runBlocking { async(CoroutineName("Calandrino")) { while (true) { logMsg("So' bischero!") BigInteger.probablePrime(1024, Random()) } } async(CoroutineName("Buffalmacco")) { while (true) { logMsg("Io pitto!") BigInteger.probablePrime(1024, Random()) } } } It just prints “So’ bischero!”
  • 15. Remember: we have to collaborate! fun main(args: Array<String>) = runBlocking { async(CoroutineName("Calandrino")) { while (true) { logMsg("So' bischero!") BigInteger.probablePrime(1024, Random()) yield() } } async(CoroutineName("Buffalmacco")) { while (true) { logMsg("Io pitto!") BigInteger.probablePrime(1024, Random()) yield() } } } yield gives control to other coroutines
  • 16. How to collaborate? yield gives control to other coroutines
  • 17. How to collaborate? delay is like Thread.sleep
  • 18. Collaborating using delay fun main(args: Array<String>) = runBlocking { async(CoroutineName("Calandrino")) { while (true) { logMsg("So' bischero!") BigInteger.probablePrime(1024, Random()) delay(10) } } async(CoroutineName("Buffalmacco")) { while (true) { logMsg("Io pitto!") BigInteger.probablePrime(1024, Random()) delay(10) } } }
  • 19. await waits for another coroutine to complete How to collaborate?
  • 20. Collaborating using await fun main(args: Array<String>) { runBlocking { async(CoroutineName("Calandrino")) { while (true) { val deferredNumber: Deferred<BigInteger> = async { bigPrime() } logMsg("Bischerata numero ${deferredNumber.await()}") } } async(CoroutineName("Buffalmacco")) { while (true) { val deferredNumber: Deferred<BigInteger> = async { bigPrime() } logMsg("Clandrino è bischero ${deferredNumber.await()} volte!") } } } }
  • 21. Collaborating using await fun main(args: Array<String>) { runBlocking { async(CoroutineName("Calandrino")) { while (true) { logMsg("Bischerata numero ${bigPrime()}") } } async(CoroutineName("Buffalmacco")) { while (true) { logMsg("Calandrino è bischero ${bigPrime()} volte!") } } } } It doesn’t work because Calandrino keeps the thread!
  • 22. Collaborating using await fun main(args: Array<String>) { runBlocking { async(CoroutineName("Calandrino")) { while (true) { logMsg("Bischerata numero ${bigPrime()}") } } async(CoroutineName("Buffalmacco")) { while (true) { logMsg("Calandrino è bischero ${bigPrime()} volte!") } } } } It doesn’t work because Calandrino keeps the thread! (Bischero!)
  • 23. suspend fun calandrinate() { while (true) { logMsg("So' bischero!") BigInteger.probablePrime(1024, Random()) yield() } } async(CoroutineName("Calandrino")) { calandrinate() } Collaborating functions are suspending ones async(CoroutineName("Calandrino")) { while (true) { logMsg("So' bischero!") BigInteger.probablePrime(1024, Random()) yield() } }
  • 24. suspend fun calandrinate() { while (true) { logMsg("So' bischero!") BigInteger.probablePrime(1024, Random()) yield() } } Collaborating functions are suspending ones The suspend modifier does not make a function either asynchronous or non-blocking. It just tells that the function could be suspended, as it could call other suspending functions (such as yield or delay). Anyway, it’s a good convention to create suspending functions that don’t block the calling thread.
  • 25. async and launch builders need a scope! CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async { bigPrime(1024) } The async and launch coroutines builders are extension functions for the CoroutineScope interface, so they must be called on an object of that type. When you see them called without an explicit scope, as inside runBlocking, it is because they are called in a block that provides an implicit this receiver of type CoroutineScope.
  • 26. async and launch builders need a scope! CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async { bigPrime(1024) } A CoroutineScope holds information on how to run coroutines, using a CoroutineContext object. We can create one of them with: • the CoroutineScope factory function; • the MainScope factory function: this works for Android, Swing and JavaFx applications, pointing to the Main UI thread; • the GlobalScope object, for top-level coroutines which are operating on the whole application lifetime; • the runBlocking function, that creates an implicit CoroutinesScope receiver; • the coroutineScope function (inside a suspend function/coroutine).
  • 27. async and launch builders need a scope! CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async { bigPrime(1024) } A CoroutineContext is something like a “set” of properties related to the coroutine. Each element of a CoroutineContext is a CoroutineContext too. Elements can be added with the + operator. So, whenever we have a CoroutineContext parameter, we can pass just one type of information, that will override the existing one, or a concatenated set of elements.
  • 28. async and launch builders need a scope! Whenever we have a CoroutineContext parameter, we can pass just one type of information, that will override the existing one, or a concatenated set of elements. The type of these three expression is CoroutineContext: • Dispatchers.Unconfined • CoroutineName("Calandrino") • Dispatchers.Unconfined + CoroutineName("Calandrino") CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async { bigPrime(1024) }
  • 29. async and launch builders need a scope! CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async { bigPrime(1024) } An important type of CoroutineContext element is the Dispatcher, that defines the thread running the coroutine.
  • 30. async and launch builders need a scope! CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async { bigPrime(1024) } Types of dispatchers: • Dispatcher.Default: backed by a shared pool of threads with maximum size equal to the number of CPU cores; for CPU/bound tasks; • Dispatcher.IO: for offloading blocking IO tasks to a shared pool of threads (the default is 64); • Dispatcher.Main: main UI thread in Android/Swing applications; • Dispathcer.Unconfined: not confined to any specific thread. The coroutine executes in the current thread first and lets the coroutine resume in whatever thread.
  • 31. async and launch builders need a scope! CoroutineScope(Dispatchers.Unconfined + CoroutineName("Calandrino")).async { bigPrime(1024) } Dispatcher can also be created with these functions: • newSingleThreadContext: one thread per coroutine; • newFixedThreadPoolContex: a fixed size thread pool; • asCoroutineDispatcher extension function on Java Executor.
  • 32. The launch builder fun main(args: Array<String>) = runBlocking { val job: Job = launch(Dispatchers.Unconfined) { ConsoleProgressBar().showContinuously() } println("A big prime number: ${bigPrime(2048)}") job.cancel() } The launch builder returns a Job that can be used to control the execution of the coroutine.
  • 33. Parent-child hierarchies for Jobs Parent jobs wait the end of all their children Cancellation of a parent leads to immediate cancellation of all its children fun main(args: Array<String>) = runBlocking { val job: Job = launch(Dispatchers.Unconfined) { launch { launch { delayAndLog() } delayAndLog() } delayAndLog() } println("Here is a big prime number: ${bigPrime(2048)}") job.cancel() }
  • 34. Why coroutines? (1..100_000).forEach { launch { while (true) delay(10_000) } }
  • 35. Why coroutines? (1..10_000).forEach { thread(start = true) { while (true) Thread.sleep(10_000) } }
  • 36. Why coroutines? (1..10_000).forEach { thread(start = true) { while (true) Thread.sleep(10_000) } } By the way: it works on Windows! J
  • 37. Good reads Kotlin Coroutines in Android - Basics https://medium.com/swlh/kotlin-coroutines-in-android-basics-9904c98d4714 Concurrency is not parallelism https://kotlinexpertise.com/kotlin-coroutines-concurrency/ Blocking threads, suspending coroutines https://medium.com/@elizarov/blocking-threads-suspending-coroutines-d33e11bf4761 Coroutines: Suspending State Machines https://medium.com/google-developer-experts/coroutines-suspending-state-machines-36b189f8aa60 Coroutines hands-on https://play.kotlinlang.org/hands-on/Introduction%20to%20Coroutines%20and%20Channels/